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

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 bowdlerisierte Version meines Called-from-Cron-Skripts, das 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 es 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

Aber die ssh -vvvAusgabe zeigt, dass es genau dann fehlschlägt, 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 erwartet, dass ich die Passphrase für eintippe ~/.ssh/id_dsa, was bei Cron-Jobs natürlich nicht funktioniert.

Das alles funktionierte in Snow Leopard.

Beachten Sie, dass ich den Schlüsselbundzugriff so eingerichtet habe, dass ssh, ssh-agent, und ssh-addmeine Passphrase für meine .ssh/id_dsaDatei lesen dürfen - daher kann ich von einer Terminal-Eingabeaufforderung aus SSH ausführen, ohne jemals meine Passphrase eingeben zu müssen.

Muss ich dieses Problem ssh-addirgendwann in meinem Anmeldeprozess ausführen? Das Ausführen von einer Standard-Bash-Eingabeaufforderung hilft dem Cron-Job nicht (obwohl es mich seltsamerweise zur Eingabe meiner Passphrase auffordert ... was meiner Meinung nach aufgrund der Konfiguration des Schlüsselbundzugriffs nicht erforderlich ist).

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

ANMERKUNG 2 - Mir ist klar, dass SSH-Schlüssel ohne Passphrase mein Problem lösen würden; Ich würde diesen Weg jedoch lieber nicht gehen.

cron ist weg. Sehen Sie sich das launchd-Tag hier für alle Arten von Hilfe an (machen Sie den Schritt - es handhabt Ports, Umgebungen und vieles mehr, so viel besser als Cron es jemals getan hat) - Ich hoffe, jemand hat eine Lösung, aber das Cron-Mojo hier altert mit Sicherheit .
cron läuft immer noch in Lion ... aber du hast Recht, ich sollte den Schritt machen. Eine XML-Datei mit mehr als 10 Zeilen, die die Arbeit einer einzelnen Zeile von crontab erledigt, ist jedoch ziemlich lahm. Vielleicht werden sie in 10 Jahren plist-Dateien auf JSON umstellen, und es wird viel Jubel geben, und 10 Jahre danach werden sie zurück zu crontab gehen, und die BSD-Graubärte werden lachen. Ich nehme an, ich werde bis dahin ein BSD-Graubart sein ...
Gerade auf launchd umgestellt, funktioniert wunderbar. Das aufgerufene Skript muss überhaupt nicht mit ssh-agent interagieren - Sie können nach dem Hashbang einfach direkt in den ssh-Befehl springen. Wenn Ihr Kommentar eine Antwort wäre, würde ich es akzeptieren =)
JSON glänzt sicherlich in vielen Fällen über XML, aber alle Plists, die vorher kamen, haben das Problem wahrscheinlich erzwungen. Ich bin einfach begeistert, dass wir einen einheitlichen, effizienten, strukturierten, datenbasierten Ersatz haben. cron und hat uns sicherlich jahrelang gute Dienste geleistet!
Ich habe überall nach zusätzlichen Webressourcen gesucht, aber ich lande immer wieder bei diesem Beitrag. Sicherlich hat jemand mehr zur Diskussion beizutragen? Ich habe versucht, ein einfaches plist zu verwenden, um mein Shell-Skript auszuführen, aber dann sendet mailx meine Benachrichtigungen nicht. Ich mag Cron immer noch und verwende es ständig in Ubuntu. Ich möchte nicht zu 10.6 zurückkehren, aber dieses Problem bringt mich um. Ich mag es nicht, zur Verwendung von launchctl gezwungen zu werden und lernen zu müssen, was sich für mich wie ein sehr umfangreiches Framework anfühlt, um Shell-Skripte im Grunde zu automatisieren. Hat jemand neue Erkenntnisse?
Der Wechsel zu launchctl hat mein Problem vollständig behoben, sodass ich aufgehört habe, mir Gedanken über cron zu machen. Wenn ich mich richtig erinnere, habe ich diese Seite benutzt. Das Generieren einer plist-Datei zum Ausführen dieses Skripts für launchctl ist ziemlich einfach.
Holen Sie sich 'Lingon X' oder LaunchControl und launchdes wird viel einfacher zu handhaben sein.

Antworten (4)

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 tatsächlich das Autorisierungsproblem. Ihre Benutzerstartaufträge (die nur ausgeführt werden, wenn Sie angemeldet sind) verwenden korrekt die SSH-Agenteninformationen, die über Ihren Schlüsselbund als Teil der Anmeldung entsperrt wurden (als Teil der standardmäßigen OS X-Schlüsselverwaltung, 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 herumschlagen zu müssen.

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 dann geladen mit:

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

Einmal geladen, wird es sofort ausgeführt und dann alle 60 Minuten erneut.

Wenn Sie dem gleichen Verfahren folgen, sollten Sie den String `ProgramArguments' mit dem richtigen Pfad zu Ihrem Skript ändern.

Tatsächlich ist cron zumindest in Lion veraltet. Hut ab, dass Sie die Antwort gefunden haben – es kann anfangs schwierig sein, in launchctl einzudringen.

Das Hinzufügen des folgenden Codes zu Ihrem Bash-Shell-Skript behebt das Problem:

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 setzt den korrekten Wert dafür SSH_AUTH_SOCK, dass informiert sshoder scpdarüber kommuniziert wird, ssh-agentwenn das Shell-Skript aus gestartet wird cron.

Dies löste das Problem, bei dem scp nicht über launchd in einem Shell-Skript funktionierte, obwohl es über die normale Befehlszeile (iTerm oder Terminal) einwandfrei funktionierte. Hervorragender Tipp.
Nur fürs Protokoll, zu El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners

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

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 mehr Leute können dabei helfen.

Sehr schöne Antwort dort . Danke, dass du es gepostet hast.

Für alle, die dies jetzt finden, versuchen, dies in El Capitan zum Laufen zu bringen, und immer noch zögern, Ihren einzeiligen Cron-Job in ein Launchd-Skript umzuwandeln, funktioniert die Antwort von Werner Antweiler immer noch, aber der Pfad hat sich geändert. Folgendes hat bei mir funktioniert:

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

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

Ich konnte dies nicht als Kommentar zu seiner Antwort einreichen, da mir der Ruf fehlt, aber ich wollte sie nicht verlassen, ohne dies zu aktualisieren, da es mir definitiv geholfen hat, es endlich einzurichten.

Bearbeitung: 30. März 2016

Nachdem ich dies eine Weile getestet habe, muss ich hinzufügen, dass dies nur funktioniert, wenn der Agent mindestens einmal während dieser Anmeldung verwendet wurde. Das Initiieren einer ssh-Verbindung oder das manuelle Ausführen von ssh-agent reicht aus, um dies zu tun. 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 mit dem Skripteditor eine .app mit dem Folgenden gespeichert und die resultierende App zu meinen Anmeldeelementen hinzugefügt:

do shell script "/path/to/startup.sh"
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. Wenn Sie das getan haben, müssen Sie sich nur beim Mac anmelden, um alles einzurichten. Der von Ihnen gepostete Socket-Pfad ist der Ort, an dem sie aufbewahrt werden, wenn SIE ssh-agent manuell ausführen (und Ihre Passphrase manuell eingeben). Suchen Sie auf El Cap nach dem Laden des Schlüsselbunds den Sockel über ls /private/tmp/com.apple.launchd.*/Listeners. Sie müssen nichts tun, außer sich bei Mac anzumelden.
launchd ist definitiv der "offizielle" Weg, aber für diejenigen, die cron weiterhin verwenden möchten, dient dies als praktikable Problemumgehung. In meinen Tests reichte das einfache Anmelden nicht aus, um einen im Schlüsselbund gespeicherten Schlüssel per Cron funktionieren zu lassen. Der von Ihnen aufgelistete Pfad existiert jedoch definitiv. Wenn das generiert wird, sobald Sie sich anmelden, und immer noch für Cron funktioniert, reicht es wahrscheinlich aus, die von mir aufgeführte Startskriptmethode zu überspringen. Zumindest einen Test wert - danke!
Ich habe dies für einen Backup-Prozess eingerichtet und es läuft seit über einer Woche sauber – über Neustarts hinweg.