Wir möchten unison
zwei Server synchronisieren. In der Kommandozeile und in Bash-Dateien funktioniert der folgende Befehl einwandfrei:
unison -batch /var/www/html/test ssh://host-2//var/www/html/test
Dateien werden synchronisiert und unison.log
aktualisiert. Soweit, so gut.
in Kombination mit einer Einstellungsdatei wie .unison/default.prf
und durch einfaches Ausführen unison
von der Kommandozeile wie beschriebenHier, alles funktioniert auch gut.
Wir haben auch incrond
den Cron-Daemon inotify installiert und er läuft reibungslos. Der folgende Cron-Job wird problemlos ausgeführt:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE touch /root/test
/root/test
wird jedes Mal aktualisiert, wenn ich Änderungen an Dateien in/var/www/html/test
So weit, so gut! Aber die einzigen Dinge, die mit der Incrontab nicht funktionieren, sind:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/bin/unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/local/sbin/unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison -batch /var/www/html/test ssh://host-2//var/www/html/test
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/bin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/local/sbin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test'
In der unison.log
Datei wird nichts angezeigt, geschweige denn eine Aktualisierung des Remote-Servers. Das Folgende gibt auch nichts aus.
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison &> /root/test.log
/root/test.log
wird nicht einmal erstellt.
Ein weiterer Test mit einer Batchdatei namens sync.sh
funktioniert ebenfalls nicht.
in der Incrontab:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /root/sync.sh
und in sync.sh
:
#!/bin/bash
touch /root/test
/usr/bin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test
Auch hier /root/test
wird es problemlos berührt, d. h. inofify funktioniert jedes Mal einwandfrei, wenn ich eine Datei in aktualisiere /var/www/html/test
, aber wieder kommt überhaupt kein Ergebnis von unison
.
/var/log/cron sieht folgendermaßen aus:
May 21 06:33:44 Host-1 incrond[28339]: (root) CMD (sh /root/sync.sh)
und es unison.log
wird überhaupt nicht aktualisiert.
Schlussfolgerungen:
inotify
funktioniert einwandfrei, erkennt jede Änderung im Dateisystem und führt eine Aufgabe aus, ausgenommen jedeunison
Aufgabe.unison
funktioniert einwandfrei über die Befehlszeile und im Batch, außer wenn es vomincrond
Daemon aufgerufen wird.
Übersehe ich etwas?
Antwort1
Um eine SSH-Verbindung herzustellen, muss sich der Client beim Server authentifizieren. Sie verwenden wahrscheinlich eine schlüsselbasierte Authentifizierung mit einem Schlüssel, der in einer kennwortgeschützten Datei gespeichert und in den SSH-Agenten geladen wird. Der SSH-Client weiß über die Umgebungsvariable , wie er den Agenten findet SSH_AUTH_SOCK
. Bei einem Cron- oder Incron-Job ist die Umgebung nicht dieselbe wie in Ihrer interaktiven Sitzung, sondern ziemlich minimal, ohne SSH_AUTH_SOCK
, sodass der SSH-Client keine Verbindung zum Remote-Computer herstellen kann.
Wenn die SSH-Verbindung nicht hergestellt werden kann, beginnt Unison nicht einmal mit der Suche nach zu synchronisierenden Dateien und es wird nichts geschrieben unison.log
.
Es gibt Fehlermeldungen im Standardfehler des Skripts, aber Sie protokollieren sie nirgends. Fügen Sie exec 2>&1 >>~/.unison-sync.log; date
am Anfang Ihres Skripts etwas wie hinzu.
Damit die SSH-Verbindung funktioniert, müssen Sie entweder dafür sorgen, dass der Unison-Job Zugriff auf Ihren Agenten hat, oder einen passwortlosen Schlüssel einrichten. Wenn Sie Ihren Agenten verwenden möchten, lesen SiePer SSH über Shell-Skript in Crontab keine Verbindung zum Remote-Computer möglich; aber dann funktioniert es nur, wenn Sie angemeldet sind. Wenn die Synchronisierung immer funktionieren soll, ist ein passwortloser Schlüssel die einzige Lösung. Da Sie Unison und damit SSH als Root ausführen, muss der private Schlüssel in sein /root/.ssh
, nicht auf Ihrem Konto. Dasselbe gilt für alle relevanten Optionen in .ssh/config
. Auf der Serverseite können Sie den öffentlichen Schlüssel nur zum Ausführen eines bestimmten Unison-Befehls mit einer command=…
Direktive in autorisieren .ssh/authorized_keys
(sieheErstellen eines UNIX-Kontos, das nur einen Befehl ausführtfür ein Beispiel). Mit einer Befehlseinschränkung kann jemand, der Zugriff auf das lokale Root-Konto erhält, nur diesen bestimmten unison …
Befehl ausführen host-2
. Ich weiß nicht, ob Unison auf diese Weise dazu verleitet werden kann, beliebigen Code auszuführen.