ssh-under-cron funktioniert unter OS X 10.7 Lion nicht mehr

12

Ich habe gerade ein Upgrade von Snow Leopard auf Lion durchgeführt und meine Cron-Jobs, die ssh verwenden, funktionieren nicht mehr. Es scheint, dass ssh-agent nicht mehr wie erwartet funktioniert.

Hier ist eine Bowdler-Version meines Called-from-Cron-Skripts, die unter Snow Leopard hervorragend funktioniert hat:

#!/bin/bash
whoami # just to verify I'm running as myself, not root
ssh-agent # just to see what it outputs    
eval `ssh-agent`
ssh -vvv REMOTESERVER ls

Wenn dieses Skript an der Eingabeaufforderung ausgeführt wird, funktioniert es wie erwartet.

Wenn von Cron ausgeführt wird, funktioniert es nicht. Die Ausgabe von ssh-agent sieht normal aus:

SSH_AUTH_SOCK=/tmp/ssh-QRxPUMRxbu/agent.17147; export SSH_AUTH_SOCK;
SSH_AGENT_PID=17148; export SSH_AGENT_PID;
echo Agent pid 17148;
Agent pid 17150

Die ssh -vvvAusgabe zeigt jedoch, dass es nicht richtig funktioniert, wenn der private Schlüssel gelesen werden soll:

debug1: Server accepts key: pkalg ssh-dss blen 818
debug2: input_userauth_pk_ok: fp ...
debug3: sign_and_send_pubkey: DSA ...
debug1: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: Device not configured
debug2: no passphrase given, try next key

Mit anderen Worten, es wird erwartet, dass ich die Passphrase für eingebe ~/.ssh/id_dsa , was bei Cronjobs natürlich nicht funktioniert.

Dies alles funktionierte in Snow Leopard.

Beachten Sie, dass ich so , dass Schlüsselbund - Setup haben ssh, ssh-agentund ssh-adderlaubt mein Passwort lesen für meine.ssh/id_dsa Datei - als Ergebnis kann ich über eine Terminal-Eingabeaufforderung SSH ausführen, ohne jemals meine Passphrase eingeben zu müssen.

Ist das Problem, das ich ausführen muss ssh-add irgendwann in meinem Anmeldevorgang muss? Das Ausführen von einer Standard-Bash-Eingabeaufforderung aus hilft dem Cron-Job nicht weiter (obwohl es mich seltsamerweise zur Eingabe meiner Passphrase auffordert ... was meiner Meinung nach in der Konfiguration von Keychain Access nicht unbedingt erforderlich ist).

HINWEIS 1 - Bevor Sie mich umleiten - Ich bin mir bewusst, dass es hier eine ähnliche Frage gibt ( Mac OS X Lion und sshpass ), aber es geht speziell um ein Programmsshpass , das ich nicht verwende (obwohl ich glaube, dass diese Frage auch von diesem beantwortet werden würde ).

ANMERKUNG 2 - Mir ist klar, dass passphrasenlose SSH-Schlüssel mein Problem lösen würden. Ich würde es jedoch vorziehen, diesen Weg nicht zu gehen.

John Hart
quelle
2
cron ist weg. Siehe das launchd-Tag hier für alle Arten von Hilfe (machen Sie den Umzug - es handhabt Ports, Umgebung und vieles mehr als je zuvor) - Ich hoffe, jemand hat eine Lösung, aber das cron mojo hier altert mit Sicherheit .
bmike
3
cron läuft immer noch in Lion ... aber du hast recht, ich sollte den Umzug machen. Eine XML-Datei mit mehr als 10 Zeilen für die Arbeit einer einzelnen Zeile crontab ist jedoch ziemlich lahm. Vielleicht werden sie in 10 Jahren Plist-Dateien auf JSON umstellen, und es wird viel Freude geben, und 10 Jahre später kehren sie zu Crontab zurück, und die BSD-Graubärte werden lachen. Ich nehme an, ich werde bis dahin ein BSD-Graubart sein ...
John Hart
1
Gerade auf launchd umgestellt, wirkt ein Zauber. Das aufgerufene Skript muss überhaupt nicht mit ssh-agent interagieren - Sie können direkt nach dem Hash-Bang in den Befehl ssh springen. Wenn Ihr Kommentar eine Antwort wäre, würde ich es akzeptieren =)
John Hart
JSON scheint in vielen Fällen sicherlich über XML zu glänzen, aber alle Plists, die vorher kamen, haben das Problem wahrscheinlich erzwungen. Ich bin nur gekitzelt, dass wir einen einheitlichen, effizienten, strukturierten, datenbasierten Ersatz haben. cron und hat uns sicher ewig gut gedient!
bmike
Ich habe hoch und niedrig nach zusätzlichen Webressourcen gesucht, aber ich komme immer wieder auf diesen Beitrag zurück. Sicherlich hat jemand mehr zur Diskussion beizutragen? Ich habe versucht, mein Shell-Skript mit einer einfachen Plist auszuführen, aber dann sendet mailx meine Benachrichtigungen nicht. Ich mag cron immer noch und ich benutze es die ganze Zeit in Ubuntu. Ich möchte nicht auf 10.6 zurückgehen, aber dieses Problem bringt mich um. Ich mag es nicht, gezwungen zu sein, launchctl zu verwenden und zu lernen, was sich für mich wie ein sehr umfangreiches Framework anfühlt, um Shell-Skripte grundsätzlich zu automatisieren. Hat jemand neue Einsichten?

Antworten:

10

Für alle, die auf dieser Seite landen, wurde mir klar, dass ich die Antwort posten sollte:

Die Verwendung von launchd anstelle von cron behebt in der Tat das Autorisierungsproblem. Ihre vom Benutzer gestarteten Jobs (die nur ausgeführt werden, wenn Sie angemeldet sind) verwenden die über Ihren Schlüsselbund entsperrten SSH-Agenteninformationen korrekt als Teil der Anmeldung (im Rahmen der Standard-OS X-Schlüsselverwaltung ist keine andere Software erforderlich).

Um meine Interaktionen mit launchd zu minimieren, habe ich einen einzelnen launchd-Job erstellt, der ein Bash-Skript aufruft. Auf diese Weise kann ich das Skript einfach bearbeiten, ohne mich mit launchd zu befassen.

Hier ist die launchd-Datei:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.mycron.hourly</string>

  <key>ProgramArguments</key>
  <array>
    <string>/Users/john/bin/cron.hourly</string>
  </array>

  <key>Nice</key>
  <integer>1</integer>

  <key>StartInterval</key>
  <integer>3600</integer> <!-- start every X seconds -->

  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Ich habe die Datei in gespeichert ~/Library/LaunchAgents/com.mycron.hourly.plistund sie dann geladen mit:

launchctl load ~/Library/LaunchAgents/com.mycron.hourly.plist

Einmal geladen, läuft es sofort und dann alle 60 Minuten wieder.

Wenn Sie auf die gleiche Weise vorgehen, möchten Sie die Zeichenfolge `ProgramArguments 'mit dem richtigen Pfad zu Ihrem Skript ändern.

John Hart
quelle
2
In der Tat ist Cron zumindest in Lion veraltet. Ein großes Lob für das Finden der Antwort - launchctl kann anfangs schwierig sein.
Zwerdlds
7

Durch Hinzufügen des folgenden Codes zu Ihrem Bash-Shell-Skript wird das Problem behoben:

declare -x SSH_AUTH_SOCK=$( find /tmp/launch-*/Listeners -user your_user -type s | head -1 )

Ersetzen Sie your_userdurch Ihren eigenen Benutzernamen.

Dieser Code legt den korrekten Wert für SSH_AUTH_SOCKInformationen sshoder scpInformationen zur Kommunikation fest, ssh-agentwenn das Shell-Skript gestartet wird cron.

Werner Antweiler
quelle
Dies löste das Problem, bei dem scp nicht über launchd in einem Shell-Skript funktioniert, obwohl es über die reguläre Befehlszeile (iTerm oder Terminal) einwandfrei funktioniert. Sehr guter Tipp.
TJ Luoma
Nur zur Erinnerung, am El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan
1

Ich würde eine verbesserte Sicherheit wie Sandbox erwarten und Änderungen, um die Dinge weiter auf 64-Bit zu verschieben, verursachen unerwarteten Kummer.

Es ist per se keine Antwort, aber launchd bekommt heutzutage die ganze Liebe von Apple.

Es behebt das Cron-Problem nicht, ist aber stabiler und es können mehr Leute damit helfen.

bmike
quelle
Sehr schöne Antwort da . Vielen Dank für die Veröffentlichung.
bmike
1

Für jeden, der dies jetzt findet, versucht, es in El Capitan zum Laufen zu bringen, und weiterhin zögert, Ihren einzeiligen Cron-Job in ein Startskript umzuwandeln, funktioniert die Antwort von Werner Antweiler weiterhin, aber der Pfad hat sich geändert. Das Folgende hat bei mir funktioniert:

declare -x SSH_AUTH_SOCK=$(find /var/folders/*/*/*/*/agent.* -user your_user -type s | head -1)

HINWEIS : Denken Sie daran, Ihren_Benutzer durch Ihren Benutzernamen zu ersetzen!

Es würde mir nicht erlauben, dies als Kommentar zu seiner Antwort einzureichen, da mir der Ruf fehlt, aber ich wollte sie nicht verlassen, ohne dies zu aktualisieren, da es mir definitiv half, es endlich einzurichten.

Edit: 30. März 2016

Nachdem ich dies eine Weile getestet habe, muss ich hinzufügen, dass dies nur funktioniert, wenn der Agent während dieser Anmeldung mindestens einmal verwendet wurde. Dazu genügt es, eine SSH-Verbindung herzustellen oder den SSH-Agenten manuell auszuführen. Ein Startskript kann auch verwendet werden, wenn Sie möchten, dass es automatisch ausgeführt wird. Ich habe eine startup.sh erstellt, die nur ssh-agent ausführt, und dann mithilfe des Skript-Editors eine .app mit den folgenden Angaben gespeichert und die resultierende App zu meinen Anmeldeelementen hinzugefügt:

do shell script "/path/to/startup.sh"
Petie
quelle
Ich löse das gerade, und das ist nicht der beste Weg. launchd ist anscheinend der richtige Weg, aber für cron möchten Sie Ihren ssh-Schlüssel (mit Passphrase) in Ihrem Schlüsselbund einrichten. Sobald Sie dies getan haben, können Sie alles einrichten, indem Sie sich beim Mac anmelden. In dem von Ihnen angegebenen Socket-Pfad werden sie gespeichert, wenn SIE ssh-agent manuell ausführen (und Ihre Passphrase manuell eingeben). Sobald der Schlüsselbund auf El Cap geladen ist, finden Sie die Steckdose über ls /private/tmp/com.apple.launchd.*/Listeners. Sie müssen nichts weiter tun, als sich bei Mac anzumelden.
Joe
launchd ist definitiv die "offizielle" Möglichkeit, dies zu tun, aber für diejenigen, die weiterhin cron verwenden möchten, ist dies eine praktikable Lösung. In meinen Tests reichte es nicht aus, sich einzuloggen, um einen im Schlüsselbund gespeicherten Schlüssel über cron funktionsfähig zu machen. Der von Ihnen angegebene Pfad existiert jedoch definitiv. Wenn dies generiert wird, sobald Sie sich anmelden und weiterhin für cron arbeiten, reicht es wahrscheinlich aus, die aufgeführte Startskriptmethode zu überspringen. Zumindest einen Test wert - danke!
Petie
Ich habe dies für einen Sicherungsvorgang eingerichtet und es läuft jetzt seit über einer Woche sauber - über Neustarts hinweg.
Joe