In meiner Firma verrichten schon seit gut 10 Jahren zwei alte Macs ihren Dienst als Server. Zwar schlagen sie sich immer noch zuverlässig und wacker, aber ich wollte sie lieber ersetzen, bevor sie den Abgang machen.
Ersatz ist ein virtueller Ubuntu Server in Version 16.04, den ich frisch von unserer IT installiert bekommen habe.

Im Folgenden möchte ich mehr für mich selbst alle Schritte dokumentieren, die ich ausgeführt hatte, um aus dem frisch installierten Server meinen für die Praxis benötigten xDaemon-Server zu erstellen.
Da der Ubuntu Server standardmäßig über keinen Desktop/UI verfügt, erfolgen alle Schritte von meinem Mac aus über einen ssh-Zugriff oder hier und da über ein Web-Interface.

Neuen Nutzer mit root-Rechten erstellen

Der bereits angelegte Benutzer hieß lokaladmin.
Ich bleibe lieber wie bei den vorherigen Servern bei xdaemon (ist auch etwas kürzer).

sudo useradd -d /home/xdaemon -m xdaemon # Neuen Benutzer inklusive Home-Directory anlegen
sudo passwd  xdaemon                     # Passwort für Benutzer vergeben
sudo usermod -aG sudo xdaemon            # Mit su-Rechten ausstatten
                                         # ...und noch anderen interessanten Gruppen hinzufügen...
sudo usermod -aG adm,cdrom,dip,plugdev,lpadmin,sambashare xdaemon
sudo chsh -s /bin/bash xdaemon           # Login-Shell von sh auf bash umstellen

Dann noch meine Shell-Kniffe in die ~/.bash_aliases hinzufügen (

.bash_aliases
wird, falls vorhanden, automatisch über
.bashrc
geladen. Siehe
.bashrc
, Zeile 104).

Danach die SSH-Authentifizierung durch Schlüssel auf meiner Workstation einrichten und auf selbiger ein Alias für den schnellen SSH-Zugriff im

~/.bash_profile
einrichten.

alias xdaemon='ssh xdaemon@172.17.99.99'

Nach dem nächsten Shell-Login von meinem lokalen Rechner aus sollte ich mit einem einfachen Befehl

xdaemon
auf der Konsole des Ubuntu-Servers sein.

Proxy konfigurieren

Um in einem Firmennetzwerk Internetzugang zu haben, kommt man natürlich auch nicht drumherum, den Proxy-Server zu definieren.
Dafür habe ich in der /etc/profile eine Proxy-Adresse für alle Protokolle hinterlegt.

export http_proxy=http://xdaemon:seinnetzwerkpass@172.17.99.1:80
export ALL_PROXY=$http_proxy

Natürlich kann man für verschiedene Protokolle auch verschiedene Proxys/Ports ansteuern.

export http_proxy=http://xdaemon:seinnetzwerkpass@172.17.99.1:80
export https_proxy=https://xdaemon:seinnetzwerkpass@172.17.99.1:443
export ftp_proxy=http://xdaemon:seinnetzwerkpass@172.17.99.1:21
export ALL_PROXY=$http_proxy

Bei welchen Adressen auf den Proxy verzichtet werden soll, bestimmt

no_proxy

export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"

Frisst das eine oder andere Programm den Proxy-Server nicht und meint, keine Internetverbindung zu bekommen, kann es daran liegen, dass es nach der Proxy-Variable in Versal-Form sucht.
In diesem könnte es hilfreich sein, zusätzlich zu

http_proxy
& Co auch noch
HTTP_PROXY
& Co zu definieren.

Die Paketverwaltung apt-get verlässt sich leider überhaupt nicht auf diese Konfiguration. Hierfür ist es notwendig, die Datei 95proxies im Verzeichnis /etc/apt/apt.conf.d/ zu erstellen und nochmals mit den Proxy-Daten zu füllen.
Bitte das Semikolon am Ende einer Zeile nicht vergessen, sonst bekommt man die amüsante Fehlermeldung

zusätzlicher Unsinn am Dateiende
beim verwenden von apt-get

#/etc/apt/apt.conf.d/95proxies:
Acquire::http::proxy  "http://xdaemon:seinnetzwerkpass@172.17.99.1:80";
Acquire::https::proxy "https://xdaemon:seinnetzwerkpass@172.17.99.1:443";
Acquire::ftp::proxy   "http://xdaemon:seinnetzwerkpass@172.17.99.1:21";

Webmin installieren

Webmin ist eine tolle Sache, einen Server von fern zu verwalten und kann per Ubuntu-Paketverwaltung installiert werden, wenn man die zusätzlich nötigen Quellen dem System mitteilt.

Dazu am Ende von

 /etc/apt/sources.list
die beiden Zeilen

deb http://download.webmin.com/download/repository sarge contrib
deb http://webmin.mirror.somersettechsolutions.co.uk/repository sarge contrib

hinzufügen und das Zertifikat der Entwickler zum System hinzufügen

wget http://www.webmin.com/jcameron-key.asc
sudo mv jcameron-key.asc /root/jcameron-key.asc
sudo apt-key add /root/jcameron-key.asc

Dann letztendlich die Installation

sudo apt-get update
sudo apt-get install webmin

Webmin ist danach unter der Adresse

https://<ubuntu-server>:10000
zu erreichen. Leider habe ich in unserem Netzwerk Probleme, die interne
https
-Adresse zu öffnen und de-aktiviere in der Config-Datei /etc/webmin/miniserv.conf deswegen bei Webmin SSL, um über
http://<ubuntu-server>:10000
auf Webmin zugreifen zu können.
Die Zeile ssl=1 umwandeln in ssl=0 und Webmin neustarten:
sudo /etc/init.d/webmin restart

Zwischendurch etwas Kosmetik

Der Hinweis auf die Dokumentation, der jedes Mal erscheint, wenn man sich per SecureShell einloggt, nervt recht schnell.

Ist aber auch schnell abgeschafft, wenn man dem verursachenden Skript, das der Message of the day diese Zeile hinzufügt, die Ausführ-Rechte entzieht:

sudo chmod -x /etc/update-motd.d/10-help-text

Verzeichnis-Freigaben einrichten

Freizugebende Ordner kann man am Ende von /etc/samba/smb.conf eintragen:

[hotfolders]
   comment = Hotfolders
   path = /home/xdaemon/hotfolders
   public = yes
   guest ok = yes
   browsable = yes
   writeable = yes

In diesem Fall handelt es sich um ein freigegebenes Verzeichnis mit Gast-Zugriff, für welches kein Passwort eingegeben werden muss.
Soll man das Verzeichnis nur mit Benutzername und Passwort mounten können, so muss man den gewünschten User (der bereits als lokaler User auf dem System vorhanden sein muss!) der smb-Benutzerdatenbank hinzufügen (und

guest ok
und
public
selbstverständlich auf
no
setzen):

sudo smbpasswd -a <benutzername des ubuntu-users>

Das darauf abgefragte Passwort ist das neue Passwort für den SMB-Zugriff, welches bei Bedarf vom vorhandenen Benutzer-Passwort abweichen kann.

Will man Zugriff für mehrere Personen gewähren und ihnen nicht unbedingt den Benutzernamen des Server-Users geben, so kann man zuvor einen weiteren Benutzer anlegen, dem der Shell-Zugang verwehrt wird:

sudo adduser --no-create-home --disabled-login --shell /bin/false <benutzername>
sudo smbpasswd -a <benutzername>

Die Konfiguration lässt sich danach mit dem Befehl

testparm
checken, Samba mit einem
sudo service smbd restart
 neustarten.

Erst hatte der Gastzugriff nicht funktioniert, darauf der Zugriff mit Benutzernamen und Passwort nicht, dann hatte gar nichts mehr funktioniert...ich weiß nicht, wie ich irgendwann zu einer Konfiguration gekommen bin, die nun so funktioniert, wie ich es gerne hätte...aber hier der zur Komplementierung der funktionierende Ausschnitt meiner smb.conf mit einem öffentlichen zugänglichen Hotfolder, einem öffentlich zugänglichen PDF-Ausgabe-Ordner (dazu kommen wir später noch), dem nicht öffentlich zugänglichen Apache-Web-Verzeichnis und dem für den Benutzer zugänglichen Benutzerordner.

/etc/samba/smb.conf
[global]
   workgroup = APFELZ_NET
   server string = %h xDaemon
   dns proxy = no
   security = user
   guest account = nobody
   map to guest = bad user
   encrypt passwords = true
   invalid users = root
   username map = /etc/samba/smbusers
   obey pam restrictions = yes
   unix password sync = yes
   unix extensions = no
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
   pam password change = yes

[homes]
   comment = Home Directories
   browseable = no
   read only = no
   valid users = %S

[hotfolders]
   comment = Hotfolders
   path = /home/xdaemon/hotfolders
   public = yes
   guest ok = yes
   browsable = yes
   writeable = yes
   read only = no
   available = yes
   force user = xdaemon
   create mode = 0666
   force create mode = 0666
   directory mask = 2777
   force directory mode = 2777
   inherit permissions = yes
   veto files = /.DS_Store/._.DS_Store/.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/
   delete veto files = yes

[pdf]
   comment = PDF-Drucker
   path = /var/spool/pdfprinter
   public = yes
   guest ok = yes
   browsable = yes
   writeable = yes
   available = yes

[web]
  comment = Web-Verzeichnis
  path = /var/www/html
  public = no
  guest ok = no
  browsable = yes
  writeable = yes
  available = yes

/home/xdaemon/hotfolders
wurde außerdem auf 777 ge
chmod
ed.

Ich hatte ziemlich lange rumgewürgt, bis die Freigabe endlich so funktionierte, wie sie sollte. Meine Erkenntnisse zur Unix-Dateifreigabe und Berechtigungen habe ich in diesem separaten Artikel festgehalten.

Freigaben anderer Server mit autofs mounten

autofs scheint nicht standardmäßig installiert zu sein, also holen wir das nach:

sudo apt-get install autofs

Falls wir auf einen Samba/Cifs-Server zugreifen wollen und hier Benutzername und Passwort bei der Anmeldung mitgeben müssen, brauchen wir noch Folgendes:

sudo apt-get install cifs-utils

In der nun vorhandenen Datei /etc/auto.master fügen wir einen Eintrag hinzu, der auf unsere Samba-Mounts verweist, die in das Verzeichnis /smb erfolgen sollen:

/smb     /etc/auto.smb        -nosuid

Das angegebene Verzeichnis smb auf Root-Ebene muss manuell angelegt werden.

Die bereits vorhandene auto.smb benenne ich in auto.smb.bak um (sicher ist sicher) und erstelle eine neue auto.smb mit meinen manuell erstellten Freigaben, wie zum Beispiel

Pictures -fstype=cifs,file_mode=0777,dir_mode=0777,nounix,credentials=/etc/auto-credentials/xdaemon ://192.168.178.1/mylovelypictures
Music    -fstype=cifs,vers=1.0,file_mode=0777,dir_mode=0777,nounix,credentials=/etc/auto-credentials/xdaemon ://192.168.178.2/itunesmusic

Der Teil credentials=/etc/auto-credentials/xdaemon ist nur verwendbar, wenn cifs-utils installiert wurde (siehe ein paar Zeilen weiter oben).
Sollte der Server, auf welchen wir zugreifen wollen, nur das ältere SMB1-Protokoll verwenden, kann dies mit einem vers=1.0 erzwungen werden (Bei Freigabe "Music" als Beispiel verwendet).

Stolperstein Zugriffsrechte

Eigentlich stößt man bei der Recherche immer auf auto.smb-Einträge wie etwa

Pictures -fstype=cifs,rw,credentials= [...]

Das resultierte bei mir dann darin, dass alle Dateien auf dem fernen Server root:root gehörten und für alle anderen allerhöchstens Leserechte zur Verfügung standen.
Durch Ersetzen von rw in file_mode=0777,dir_mode=0777,nounix konnte dem Abhilfe geschaffen werden. Dateien auf den gemounteten Servern gehören zwar immer noch Benutzer und Gruppe root, haben aber nun für alle Schreib-/Lese-/Ausführrechte (

file_mode
und
dir_mode
können natürlich je nach Wunsch angepasst werden).

Stolperstein Authentifizierung

Bei meinem vorherigen Server konnte ich die Zugangsdaten für den Zugriff auf den Server direkt in dieser auto.smb mit der Server-URL mitgeben (z.B. ://meinbenutzername:geheimespasswort@192.168.178.2/itunesmusic).
Unter Ubuntu habe ich mir aber die Zähne ausgebissen, weil ich beim Zugriffsversuch auf die Freigabe immer wieder die Fehlermeldung No such file or directory erhielt. Soviel wie "irgendwas hat da nicht funktioniert".

Durch Verwendung einer ausgelagerten credentials-Datei (/etc/auto-credentials/xdaemon) funktionierte die Sache dann endlich. Nicht weiter tragisch, da die meisten Server in meinem Fall sowieso denselben Benutzernamen und Passwort verwenden – ansonsten würden mehrere credentials-Dateien benötigt werden.
Zwar sind auch hier Benutzername und Passwort im Klartext gespeichert, was in meinem Fall aber nicht weiter tragisch ist, da ich die einzige Person mit Zugriff auf den Ubuntu-Server bin.
Die credentials-Datei hat folgenden simplen Aufbau:

username=derbenutzername
password=dasstrenggeheimepasswort

Hierfür müssen bei neueren Ubuntu-Versionen die cifs-utils installiert sein:

sudo apt-get install cifs-utils

Dienst Starten

Mit

sudo service autofs start
starten wir den Dienst.

Apache

PHP

Apache ist zwar standardmäßig installiert und aktiviert, PHP müssen wir seltsamerweise nachinstallieren.

Während der Übergangszeit von PHP5 zu PHP7 war es wohl noch notwendig, php5 oder php7.0 bei der Installation zu verwenden, inzwischen funktioniert php7.0 nicht mehr und man muss wohl nur php verwenden.

sudo apt-get install php
sudo apt-get install libapache2-mod-php
sudo a2enmod php7.0 # Nur, falls php7.0.conf und php7.0.load nicht in /etc/apache2/mods-enabled/ vorhanden sind

sudo service apache2 restart

CGI-BIN

CGI-Skripte waren bei meiner Standardinstallation nicht so wirklich aktiviert, obwohl es zuerst den Anschein machte.

Zuerst sollte man prüfen, ob die Datei

/etc/apache2/conf-enabled/serve-cgi-bin.conf
existiert. Falls nicht, sollte zumindest
/etc/apache2/conf-available/serve-cgi-bin.conf
existieren, welches man dann zu den aktivierten Konfigurationen rüberlinkt:

cd /etc/apache2/
sudo ln -s conf-available/serve-cgi-bin.conf conf-enabled/serve-cgi-bin.conf

Dasselbe Spiel gilt für die Datei

mods-enabled/cgi.load
– falls nicht unter den
mods-enabled
, dann linken:

cd /etc/apache2/
sudo ln -s mods-available/cgi.load mods-enabled/cgi.load

Danach sollte ein Apache-Neustart die CGI-Funktion zum Laufen bringen:

sudo service apache2 restart

Wohin mit den Perl-/Bash-Skripten und unter welcher Adresse rufe ich sie im Browser auf?
Darüber gibt die im ersten Schritt erwähnte Datei

/etc/apache2/conf-enabled/serve-cgi-bin.conf
Auskunft. Die Zeile
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

zeigt uns als erstes den Web-Pfad und als zweites den lokalen Dateipfad.
Speichere ich also das Skript
/usr/lib/cgi-bin/test.pl
, so könnte ich es unter der Adresse
http://meinserver/cgi-bin/test.pl
 aufrufen.

Die im cgi-bin-Verzeichnis gespeicherten Skripte müssen immer Ausführbar sein. Also zum Beispiel mit

sudo chmod +x /usr/lib/cgi-bin/test.pl
ausführbar machen.

Datenbanken

mySQL-Server

Der mySQL-Server ist standardmäßig bei einer Ubuntu-Neuinstallation an Board, bedarf aber noch etwas Einrichtung.

Installiert und eingerichtet wird mysql mit:

sudo apt install mysql-server
sudo mysql_secure_installation

In älteren Versionen konnte das root-Passwort (welches nichts mit dem Unix-root-User zu tun hat) mit einem der folgenden Befehle gesetzt werden, was nun nicht mehr möglich ist.

sudo mysqladmin -u root password "<mein neues passwort>"
sudo mysqladmin -u root -p password "<mein neues passwort>"

Außerdem konnte man sich früher mal auf diesem Weg beim mysql-Server anmelden, um Nutzer und Tabellen anzulegen:

mysql --user=root --password=<mein passwort>

dies geht in der aktuellen Version eher so:

sudo mysql

Andere Benutzer anlegen:

GRANT ALL PRIVILEGES ON *.* TO 'xdaemon'@'localhost'  IDENTIFIED BY 'xdaemon_passwort' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'xdaemon'@'%'  IDENTIFIED BY 'xdaemon_passwort' WITH GRANT OPTION;
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER,DROP ON *.* TO 'apache'@'localhost'  IDENTIFIED BY 'apache_passwort' WITH GRANT OPTION;
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON pma.* TO 'pma'@'localhost'  IDENTIFIED BY 'pma_passwort' WITH GRANT OPTION;

Bei mySQL 8 (oder auch vorher schon?) kann man einen neuen User nicht mehr alleine mit dem GRANT-Befehl anlegen:

CREATE USER 'xdaemon'@'localhost'  IDENTIFIED BY 'xdaemon_passwort';
GRANT ALL PRIVILEGES ON *.* TO 'xdaemon'@'localhost' WITH GRANT OPTION;
...

Sehr wahrscheinlich erlaubt der mySQL-Server standardmäßig nur den Zugriff per Kommandozeile von localhost aus. Von einem anderen Computer lässt sich in den meisten Installationsfällen nicht per

mysql --host myserver -u xdaemon -p
zugreifen.
Um dies zu erlauben, muss die Konfiguration /etc/mysql/my.cf angepasst und die bind-address auf 0.0.0.0 gesetzt werden (zum Zugriff von allen IP-Adressen zu erlangen; alternativ die gewünschte IP des zugreifenden Clients eintragen):

/etc/mysql/my.cf
[mysqld]
bind-address=0.0.0.0

Danach den mySQL-Dienst neu starten

sudo /etc/init.d/mysql restart

phpMyAdmin

Am angenehmsten lassen sich die lokalen Datenbanken mit phpMyAdmin verwalten.

Aktuellste Version herunterladen, enpacken und in das Web-Verzeichnis schieben:

sudo mv phpMyAdmin-x.x.x-all-languages /var/www/html/phpMyAdmin

Allerdings erwartet phpMyAdmin noch ein paar weitere PHP-Module, die wir zuvor bei der PHP-Installation noch nicht installiert hatten:

sudo apt-get install -y php-mysqli php-mbstring php-bz2 php-zip # Aktuelle Version
#sudo apt-get install -y php7.0-mysqli php7.0-mbstring php7.0-bz2 php7.0-zip # Zur PHP7-Einführung
#sudo apt-get install -y php5-mysqli php-bz2 php-zip # PHP5-Variante
sudo service apache2 restart

Dann benötigen wir noch ein vom Webserver beschreibbares config-Verzeichnis

mkdir /var/www/html/phpMyAdmin/config
sudo chown www-data:root /var/www/html/phpMyAdmin/config

Setup über Browser ausführen:
http://*computer-ip*/phpMyAdmin/setup/

Erstellte Konfiguration übernehmen:

cd /var/www/html/phpMyAdmin
sudo mv config/config.inc.php config.inc.php
sudo rm -r config

MS SQL- und mySQL-Zugriff (lokal wie extern) in Perl-Skripten

Um von meinen diversen Perl-Skripten auf Datenbanken zugreifen zu können, installiere ich analog zu diesem Artikel libtool und FreeTDS.
Das geht dank der Ubuntu-Paketverwaltung etwas leichter:

sudo apt-get install libtool
sudo apt-get install freetds-dev tdsodbc

Die Config-Datei befindet sich darauf in /etc/freetds

Die notwendigen CPAN-Module DBI und DBD::Sybase, um die Datenbanken in Perl nutzen zu können, können ganz einfach im zuvor installierten Webmin unter Sonstiges > Perl-Module (CPAN) installiert werden.

Zeitgesteuerte Aufgaben

Ubuntu setzt nicht wie der Mac auf launchd, welches auf dem Mac mit MacOS X 10.5 eingeführt wurde. Stattdessen lassen sich Skripte, die zu bestimmten Zeiten und Intervallen ausgeführt werden sollen, einfach mit crond einrichten, welches bis zu MacOS X 10.4 auch auf dem Mac Verwendung fand und dem ich seit der Einführung von launchd immer wieder hinterhertrauere.
launchd mag zwar sehr flexibel sein...aber ein cron-Job ist um einiges schneller eingerichtet:

crontab -e

Durch Leerzeichen getrennt Minute, Stunde, Tag, Monat, Wochentag (0 = Sonntag) und Kommando eintragen. Fertig.
Es können auch mehrere Zeiten (mit Komma getrennt) oder Intervalle (*/intervall) definiert werden:

*/5 * * * * /pfad/zum/kommando.sh >> /logs/mylog           # All 5 Minuten
15,30 12 * * * /pfad/zum/kommando2.sh >> /logs/mylog  2>&1 # Um 12:15 Uhr und 12:30 Uhr

Skripte werden mit den Rechten des Users ausgeführt, der die crontab erstellt hat. Um Skripte mit root-Rechten auszuführen, muss man die crontab mit root-Rechten öffnen:

sudo crontab -e

Hierbei wird eine separate crontab erstellt.

Alle crontabs liegen im Verzeichnis

/var/spool/cron/crontabs
, sollten aber nur nur
crontab -e
editiert werden.
/etc/crontab
sollte ebenso unangetastet bleiben, da diese durch Updates geändert werden könnte.

Hotfoldergesteuerte Aufgaben

Okay, ich gebe zu: Hier hatte launchd die Nase vorn: Damit konnte man auch Ordner auf Änderungen überwachen und somit Hotfolder erstellen.
Mit crond müsste ich je Hotfolder einen Task erstellen, der dauernd ausgeführt wird und mit Hilfe von

inotifywait
Ordner überwacht.

Die Lösung incron sah sehr interessant aus.
Ist auch schnell und einfach per Paketverwaltung installiert.

sudo apt-get install incron

Es gibt hier allerdings den Stolperstein, dass kein User per

incrontab -e
die cronjobs verwalten kann. Hierfür muss der eigene Nutzername erst noch in die Datei
/etc/incron.allow
eingefügt werden, die ggf. erstellt werden muss.
Danach lässt sich
incrontab -e
ausführen.

sudo pico /etc/incron.allow
#<zeilenweise Benutzernamen eintragen und speichern>
sudo chown root:incron /etc/incron.allow

Die Syntax der

incrontab
-Datei weicht vom bekannten cron ab.
Statt Zeit/Intervall und Befehl sind folgende Angaben hintereinander durch (nicht zu viele!) Leerzeichen zu machen:

/pfad/zum/ueberwachten/ordner/oder/datei Event-Flag(s) Befehl/Skript Skript-Argumente

Um dem Befehl/Skript Informationen über Ereignisse des überwachten Ordners mitzugeben, können folgende Variablen verwendet werden:

$@    Pfad des überwachten Ordners (entspricht dem im incrontab eingetragenen Pfad)
$#    Dateiname der hinzugefügten/gelöschten/geänderten Datei (ohne Pfad)
$%    Event Flags, die dieses Skript ausgelöst haben (ausgeschrieben)
$&    Event Flags, die dieses Skript ausgelöst haben (numerisch)

Die möglichen Event-Flags lauten wie folgt:

IN_ACCESS        Auf Datei wurde zugegriffen (read)
IN_ATTRIB        Metadaten wurden geändert (z.B.  permissions, timestamps, extended attributes, UID, GID,...)
IN_CLOSE_WRITE   Datei geschlossen (zuvor Schreib-Zugriff)
IN_CLOSE_NOWRITE Datei geschlossen (zuvor kein Schreib-Zugriff)
IN_CREATE        Datei oder Verzeichnis wurde in überwachtem Verzeichnis erstellt/kopiert
IN_DELETE        Datei oder Verzeichnis wurde in überwachtem Verzeichnis gelöscht
IN_DELETE_SELF   Das überwachte Verzeichnis/Ordner selbst wurde gelöscht
IN_MODIFY        Datei wurde geändert
IN_MOVE_SELF     Das überwachte Verzeichnis/Ordner selbst wurde verschoben
IN_MOVED_FROM    Datei/Verzeichnis wurde aus überwachtem Verzeichnis raus geschoben
IN_MOVED_TO      Datei/Verzeichnis wurde in das überwachte Verzeichnis geschoben
IN_OPEN          Datei wurde geöffnet
IN_ALL_EVENTS    Bei allen obigen Events

Spezial-Flag:
IN_NO_LOOP       Ãœberwachung aussetzen, bis ein vorheriger Auslöser abgeschlossen
                 wurde (um unendliche Schleifen zu verhindern)

Beispiel:

/home/xdaemon/hotfolder/konvertierung IN_CREATE,IN_MOVE /home/xdaemon/scripts/konvertierungsskript.sh $@ $#

=> Wenn eine Datei in das Verzeichnis konvertierung geschoben/kopiert wird, wird das Skript konvertierungsskript.sh ausgeführt und der Pfad zum Verzeichnis (/home/xdaemon/hotfolder/konvertierung) und der Name der verschobenen/kopierten Datei als Argumente mitgegeben.

Analog zur manuellen Ausführung:

/home/xdaemon/scripts/konvertierungsskript.sh '/home/xdaemon/hotfolder/konvertierung' 'meine_datei.jpg'

Achtung:
Leider lässt sich die Skript-Ausgabe nicht mit ++>>+ in eine Datei umleiten. Die Verwendung von

/pfad/zum/verzeichnis IN_CREATE,IN_MOVE /pfad/zu/skript.sh $@ $# >> /pfad/zum/log

in incrontab wird nicht wie erwartet funktionieren, da >> und /pfad/zum/log nur als weitere Argumente #3 und #4 an das Skript mitgegeben werden, statt direkt bei Skriptausführung interpretiert zu werden.

Mögliche Fehlermeldungen kann man laut website nur im /var/log/syslog oder /var/log/cron-Log finden (wobei ich bei letzterem nicht fündig werden konnte).

Starten des incron-Daemons:

service incron start

Meine best-practice-Verwendung von incron

Mit ein paar Ãœberraschungen muss man bei incron leben. Hier ein Beispiel einer Hotfolder-Anwendung, bei der einige Ãœberraschungen abgefangen werden:

incrontab

/pfad/zu/hotfolder IN_CREATE,IN_MOVED_TO /pfad/zu/skript.pl $@ $# $%

Nein, das am Ende der Zeile ist kein Gefluche. Hier übergebe ich den Pfad zum Hotfolder, den ich zugegebenermaßen auch fest in das Skript coden könnte, Name der eingegangenen Datei/Verzeichnisses und Events, die für das Auslösen verantwortlich waren, an mein Skript.

Das Skript hat dann folgenden Aufbau:

#!/usr/bin/perl

my $hotfolder = @ARGV[0]; # Ist in diesem Fall immer wie in incrontab /pfad/zu/hotfolder
                          # OHNE endenden Slash!
my $infile    = @ARGV[1]; # Eingegangene Datei/Verzeichnis, die den Trigger ausgelöst hat
my $trigger   = @ARGV[2]; # Entweder IN_MOVED_TO, wenn in das Verzeichnis verschoben
                          # oder IN_CREATE, wenn direkt in das Verzeichnis kopiert oder dort erstellt
                          # Falls es sich um ein Verzeichnis handelt, zusätzlich noch ein Flag IN_ISDIR

# Wenn jemand Ordner/Dateien direkt in das Verzeichnis kopiert, fängt die Skriptverarbeitung zu früh an.
# Lieber ein paar Sekunden warten, bis die Daten (hoffentlich!) vollständig sind
if ($trigger =~ m/IN_CREATE/i) { sleep(30); }

# Nehmen wir an, Zweck meines Skriptes ist es, ein JPEG zu erstellen
# (und die Eingangs-Dateien sind KEINE JPEGs) und ich gebe diese
# JPEGs auch wieder im selben Verzeichnis aus, dann verhindere ich
# hier eine Endlosschleife.
# Dasselbe könnte auch der Flag IN_NO_LOOP im incrontab verhindern
if ($infile =~ m/\.jpg$/) { exit(0); }

# incron löst auch bei .resourcen-Dateien aus. Abfangen
# (und bei (nicht)Bedarf löschen)
if ($infile =~ m/^\./) { system "rm '$hotfolder/$infile'"; exit(0); }

# Unser Hotfolder soll nur PDFs akzeptieren.
# Alles andere ignorieren oder sogar gleich löschen.
if ($infile !~ m/^\.pdf/i) { system "rm '$hotfolder/$infile'"; exit(0); }

[...]

CUPS-PDF PDF-Drucker und CUPS allgemein

Dieses Thema wurde etwas umfangreich, so musste ich es in einen separaten Artikel auslagern: Allrounder CUPS: PDF-Drucker erstellen

Paketverwaltung

Update, Upgrade & Co

Wie führt man per Kommandozeile ein Update durch, wenn einen Ubuntu beim SSH-Login freundlich darauf hinweist, dass Aktualisierungen vorhanden sind?
Hierfür gibt es mehrere Befehle:

sudo apt-get update       # liest alle in der /etc/apt/sources.list eingetragenen
                          # Paketquellen neu ein. Vor einem (eigentlichen) Update
                          # zu empfehlen
sudo apt-get upgrade      # bringt die installierten Pakete auf den neuesten Stand
                          # (laut eben aktualisierter Paketquellen)
                          # Es werden KEINE neuen Pakete installiert und auch
                          # keine Pakete Pakete de-installiert, die ggf. durch
                          # neue Abhängigkeiten unnötig geworden sind
sudo apt-get dist-upgrade # Analog "upgrade", allerdings werden hier nun neue Pakete
                          # installiert und alte de-installiert, falls sie
                          # nicht mehr benötigt werden

upgrade
oder
dist-upgrade
? Fragt man Google, tendieren die meisten Ubuntu-User zu
dist-upgrade
. Das mag nun nicht unbedingt der beste Grund sein, es auch so zu handhaben, aber ich habe auch nirgends gelesen, dass es durch das de-installieren unnötiger Pakete und ändern der Abhängigkeiten zu Problemen kam.
Von dem her lohnt es sich, in seiner
.bash_aliases
der Einfachheit halber die Zeile

alias ubuntu-update='sudo apt-get update && sudo apt-get dist-upgrade'

hinzuzufügen, so dass ein System-Update durch ein einfaches

ubuntu-update
auszulösen ist.

Und wie updated man auf eine komplett neue Systemversion?

Nach

update
und
upgrade
ein
sudo do-release-upgrade
durchführen.

Entfernen

Pakete werden nicht mit deinstall deinstalliert, sondern mit remove:

sudo apt-get remove <paketname>

Außerdem können mit
sudo apt autoremove
durch Abhängigkeiten nicht mehr benötigte Pakete automatisch entfernt werden.

Suchen

Die Paketverwaltung mit
apt-get
mag zwar ganz schick sein, aber wenn man nicht weiß, wie ein Paket genau heißt, kann man es ohne weitere Googlerei auch nicht installieren.

Mit

apt-cache search <möglicher Paketname>
(sucht einfach nur nach Paketen) oder
dpkg -l *<möglicher Paketname>*
(sucht nach Paketen und gibt außerdem an, ob diese lokal installiert sind ii oder nicht un; findet allerdings seltsamerweise nicht so viele Pakete, wie
apt-cache
) kann man nach Paketen suchen.

So findet man zum Beispiel schnell das zu PHP gehörende bzip2-Modul:

apt-cache search bzip2 | grep php

FTP-Server und User mit Zugriff auf Web-Verzeichnis

Es ist für mich praktischer, via FTP auf das Apache-Verzeichnis zuzugreifen, statt via SMB.
Dies ist mit wenigern Handgriffen eingerichtet: vsftpd installieren und noch ein paar Zeilen zur Einrichtung.

sudo apt-get install vsftpd
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak # Konfiguration zur Sicherheit backupen
sudo pico /etc/vsftpd.conf

Diese Zeilen am Ende der Konfiguration hinzufügen:

/etc/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=0002
anon_upload_enable=YES
anon_mkdir_write_enable=YES
file_open_mode=0777

Dienst neustarten und separaten FTP-User hinzufügen, der die entsprechenden Zugriffsrechte auf das Verzeichnis hat:

sudo adduser xdaemon_ftp                    # xdaemon_ftp ist der Benutzername.
                       # Nach Eingabe des Befehles ein Passwort für diesen User definieren
sudo usermod -d /var/www/html -m xdaemon_ftp # Web-Verzeichnis als Home-Verzeichnis setzen
sudo usermod -aG www-data xdaemon_ftp        # Zur www-data-Gruppe hinzufügen, um Schreibrechte zu erlangen
sudo service vsftpd restart                  # FTP-Dienst neustarten