ssh-under-cron cesse de fonctionner sous OS X 10.7 Lion

12

Je viens de passer de Snow Leopard à Lion, et mes tâches cron qui utilisent ssh ont cessé de fonctionner. Il semble que ssh-agent ne fonctionne plus comme prévu.

Voici une version bowdlerized de mon script appelé depuis cron qui fonctionnait très bien sous Snow Leopard:

#!/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

Lorsqu'il est exécuté à partir de l'invite de commandes, ce script fonctionne comme prévu.

Lorsqu'il est exécuté à partir de cron, cela ne fonctionne pas. La sortie de ssh-agent semble normale:

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

Mais la ssh -vvvsortie montre qu'elle échoue juste au moment où la clé privée doit être lue:

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

En d'autres termes, il s'attend à ce que je tape la phrase secrète pour ~/.ssh/id_dsa, ce qui bien sûr ne fonctionne pas dans les tâches cron.

Tout cela a fonctionné dans Snow Leopard.

Notez que j'ai la configuration de l'accès au trousseau pour que ssh, ssh-agentet ssh-addsoient autorisés à lire ma phrase secrète pour mon .ssh/id_dsafichier - en conséquence, je peux SSH à partir d'une invite de terminal sans jamais avoir à entrer ma phrase secrète.

Est-ce que ce problème que je dois exécuter ssh-addà un moment donné de mon processus de connexion? L'exécuter à partir d'une invite bash standard n'aide pas le travail cron (bien que, bizarrement, il me demande ma phrase secrète ... qui, je pense, n'est pas nécessaire en raison de la configuration de l'accès au trousseau).

NOTE 1 - avant de me rediriger - je suis conscient qu'il y a une question similaire ici ( Mac OS X Lion et sshpass ) mais il s'agit spécifiquement d'un programme sshpassque je n'utilise pas (bien que je pense que cette question répondra également à celle-ci) ).

NOTE 2 - Je me rends compte que les clés SSH sans mot de passe résoudraient mon problème; mais je préfère ne pas suivre cette voie.

John Hart
la source
2
cron est parti. Voir la balise launchd ici pour toutes sortes d'aide (faites le pas - il gère les ports, l'environnement et bien plus encore que cron) - J'espère que quelqu'un a une solution, mais le cron mojo ici vieillit à coup sûr .
bmike
3
cron fonctionne toujours dans Lion ... mais vous avez raison, je devrais faire le pas. Un fichier XML de 10+ lignes pour faire le travail d'une seule LIGNE de crontab est cependant assez boiteux. Peut-être que dans 10 ans, ils basculeront les fichiers plist vers JSON, et il y aura beaucoup de réjouissances, et 10 ans après, ils retourneront à crontab, et les barbes grises BSD riront. Je suppose que je serai barbe BSD d'ici là ...
John Hart
1
Je viens de passer à launchd, fonctionne à merveille. Le script appelé n'a pas du tout besoin d'interagir avec ssh-agent - vous pouvez simplement sauter directement dans la commande ssh après le hashbang. Si votre commentaire était une réponse, je l'accepterais =)
John Hart
JSON brille certainement sur XML dans de nombreux cas, mais tous les plists qui ont précédé ont probablement forcé le problème. Je suis juste content que nous ayons un remplacement unifié, efficace et structuré basé sur les données. cron et à coup sûr nous a bien servi pendant des siècles!
bmike
J'ai cherché haut et bas des ressources Web supplémentaires, mais je reviens toujours à ce poste. Quelqu'un a sûrement plus à apporter à la discussion? J'ai essayé d'utiliser un simple plist pour exécuter mon script shell mais mailx n'envoie pas mes notifications. J'aime toujours cron et je l'utilise tout le temps dans Ubuntu. Je ne veux pas revenir à 10.6 mais ce problème me tue. Je n'aime pas être obligé d'utiliser launchctl et avoir à apprendre ce qui me semble être un cadre très étendu pour automatiser essentiellement les scripts shell. Quelqu'un a-t-il de nouvelles perspectives?

Réponses:

10

Pour tous ceux qui se retrouvent sur cette page, j'ai réalisé que je devrais poster la réponse:

L'utilisation de launchd au lieu de cron résout en effet le problème d'autorisation. Vos travaux de lancement par l'utilisateur (qui ne s'exécutent que lorsque vous êtes connecté) utilisent correctement les informations de l'agent SSH qui ont été déverrouillées via votre trousseau dans le cadre de la connexion (dans le cadre de la gestion de clé OS X standard, aucun autre logiciel requis).

Pour minimiser mes interactions avec launchd, j'ai créé un seul travail launchd qui appelle un script bash. De cette façon, je peux simplement éditer le script sans avoir à lancer Launchd.

Voici le fichier launchd:

<?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>

J'ai enregistré le fichier dans ~/Library/LaunchAgents/com.mycron.hourly.plist, puis l' ai chargé avec:

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

Une fois chargé, il s'exécutera immédiatement, puis à nouveau toutes les 60 minutes.

Si vous suivez la même procédure, vous voudrez changer la chaîne `ProgramArguments 'avec le bon chemin vers votre script.

John Hart
la source
2
En effet, cron est déconseillé au moins chez Lion. Félicitations pour trouver la réponse - launchctl peut être difficile à percer au départ.
zwerdlds
7

L'ajout du code suivant à votre script shell bash résoudra le problème:

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

Remplacez-le your_userpar votre propre nom d'utilisateur.

Ce code définit la valeur correcte pour SSH_AUTH_SOCKqui informe sshou scpcomment communiquer avec ssh-agentlorsque le script shell est démarré cron.

Werner Antweiler
la source
Cela a résolu le problème que je rencontrais où scp ne fonctionnerait pas via launchd dans un script shell malgré qu'il fonctionnait bien via la ligne de commande régulière (iTerm ou Terminal). Excellent conseil.
TJ Luoma
Juste pour mémoire, sur El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov
1

Je m'attendrais à une sécurité renforcée comme le bac à sable et des changements pour déplacer davantage les choses vers 64 bits causent un chagrin inattendu.

Ce n'est pas une réponse en soi, mais launchd reçoit tout l'amour d'Apple ces jours-ci.

Il ne résout pas le problème de cron, mais est plus stable et plus de personnes peuvent l'aider.

bmike
la source
Très belle réponse là-bas . Merci de l'avoir posté.
bmike
1

Pour quiconque le trouve maintenant, essaie de faire fonctionner cela dans El Capitan, et hésite toujours à transformer votre travail cron d'une ligne en un script de lancement, la réponse de Werner Antweiler fonctionne toujours mais le chemin a changé. Ce qui suit a fonctionné pour moi:

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

REMARQUE : n'oubliez pas de remplacer votre_utilisateur par votre nom d'utilisateur!

Cela ne me permettrait pas de soumettre cela comme un commentaire sur sa réponse car je n'ai pas la réputation mais je ne voulais pas la quitter sans la mettre à jour car cela m'a définitivement aidé à la configurer.

Édition: 30 mars 2016

Après avoir testé cela pendant un certain temps, je dois ajouter que cela ne fonctionne que lorsque l'agent a été utilisé au moins une fois lors de cette connexion. Il suffit de lancer une connexion ssh ou d'exécuter manuellement ssh-agent. Un script de démarrage peut également être utilisé si vous souhaitez qu'il s'exécute automatiquement. J'ai créé un startup.sh qui exécute simplement ssh-agent, puis j'ai utilisé l'Éditeur de script pour enregistrer un .app avec les éléments suivants et j'ai ajouté l'application résultante à mes éléments de connexion:

do shell script "/path/to/startup.sh"
Petie
la source
Je résous ce problème en ce moment, et ce n'est pas la meilleure façon. launchd est apparemment la voie à suivre, mais pour cron, vous voulez configurer votre clé ssh (avec phrase de passe) dans votre trousseau. Une fois que vous avez fait cela, il vous suffit de vous connecter au Mac pour tout configurer. Le chemin de socket que vous avez publié est où ils sont conservés si VOUS exécutez ssh-agent manuellement (et tapez votre phrase secrète manuellement). Sur El Cap, une fois le trousseau chargé, trouvez la prise via ls /private/tmp/com.apple.launchd.*/Listeners. Vous n'avez rien d'autre à faire que vous connecter à mac.
joe
launchd est définitivement la façon "officielle" de le faire mais pour ceux qui veulent continuer à utiliser cron, cela constitue une solution de contournement viable. Lors de mes tests, la simple connexion ne suffisait pas à faire fonctionner une clé enregistrée avec un trousseau via cron. Le chemin que vous avez indiqué existe bel et bien. Si cela est généré dès que vous vous connectez et fonctionne toujours pour cron, il suffit probablement de pouvoir ignorer la méthode de script de démarrage que j'ai répertoriée. Cela vaut certainement la peine d'être testé - merci!
Petie
J'ai mis cela en place pour un processus de sauvegarde, et cela fonctionne correctement - à travers les redémarrages - depuis plus d'une semaine maintenant.
joe