ssh-under-cron smette di funzionare in OS X 10.7 Lion


12

Appena aggiornato da Snow Leopard a Lion, i miei lavori cron che usano ssh hanno smesso di funzionare. Sembra che ssh-agent non funzioni più come previsto.

Ecco una versione bowdlerized del mio script chiamato-da-cron che ha funzionato benissimo con 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

Quando viene eseguito dal prompt dei comandi, questo script funziona come previsto.

Quando viene eseguito da cron, non funziona. L'output di ssh-agent sembra 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

Ma il ssh -vvv l'output mostra che fallisce proprio quando la chiave privata deve essere letta:

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

In altre parole, mi aspetto che scriva la passphrase per ~/.ssh/id_dsa, che ovviamente non funziona nei lavori cron.

Tutto questo ha funzionato in Snow Leopard.

Nota che ho configurato il portachiavi in ​​modo che ssh, ssh-agent, e ssh-add sono autorizzati a leggere la mia passphrase per il mio .ssh/id_dsa file - come risultato posso SSH da un terminale senza dover inserire la mia passphrase.

È questo problema che devo eseguire ssh-add ad un certo punto nel mio processo di accesso? Eseguirlo da un prompt bash standard non aiuta il cron job (anche se, stranamente, mi viene richiesta la mia passphrase ... che non penso sia necessaria b / c della configurazione di Keychain Access).

NOTA 1 - prima di reindirizzarmi - Sono consapevole che c'è una domanda simile qui ( Mac OS X Lion e sshpass ) ma riguarda specificamente un programma sshpass che non uso (anche se credo che a questa domanda si possa rispondere anche questa).

NOTA 2 - Mi rendo conto che le chiavi SSH passphrase-less risolverebbero il mio problema; comunque preferirei non seguire questa strada.


2
cron è andato. Vedi il tag launchd qui per tutti i tipi di aiuto (fai la mossa - gestisce le porte, l'ambiente e molto più di quanto abbia mai fatto cron) - Spero che qualcuno abbia una soluzione, ma il cron mojo qui sta invecchiando per certi .
bmike

3
cron funziona ancora in Lion ... ma hai ragione, dovrei fare la mossa. Tuttavia, un file XML di 10+ linee per eseguire il lavoro di una singola LINEA di crontab è piuttosto debole. Forse tra 10 anni cambieranno i file plist in JSON, e ci sarà molta gioia, e 10 anni dopo torneranno a crontab, e i greybeards di BSD rideranno. Suppongo che sarò un BSD grigiastro da allora ...
John Hart

1
Appena passato a launchd, ha un fascino. Lo script chiamato non ha bisogno di interagire con ssh-agent - puoi semplicemente saltare direttamente al comando ssh dopo l'hashbang. Se il tuo commento fosse una risposta, lo accetterei =)
John Hart

In molti casi, JSON risplende su XML, ma tutti i dati presentati prima probabilmente hanno costretto il problema. Sono solo contento di avere una sostituzione basata su dati unificata, efficiente e strutturata. cron e di sicuro ci ha servito bene per secoli!
bmike

Ho cercato in alto e in basso per risorse web aggiuntive, ma finisco sempre su questo post. Sicuramente qualcuno ha più da contribuire alla discussione? Ho provato a usare un semplice plist per eseguire il mio script di shell ma poi mailx non invia le mie notifiche. Mi piace ancora cron e lo uso in Ubuntu tutto il tempo. Non voglio tornare al 10.6 ma questo problema mi sta uccidendo. Non mi piace essere costretto a usare launchctl e dover imparare cosa mi sembra una struttura molto espansiva per automatizzare fondamentalmente gli script di shell. Qualcuno ha qualche novità?

Risposte:


10

Per chi finisce in questa pagina, ho capito che dovevo postare la risposta:

L'uso di launchd invece di cron risolve effettivamente il problema di autorizzazione. I lavori avviati dall'utente (che vengono eseguiti solo quando si è effettuato l'accesso) utilizzano correttamente le informazioni sull'agente SSH che sono state sbloccate tramite il portachiavi come parte del login (come parte della gestione delle chiavi OS X standard, nessun altro software richiesto).

Per ridurre al minimo le mie interazioni con launchd, ho creato un singolo lavoro launchd che chiama uno script bash. In questo modo posso semplicemente modificare lo script senza occuparmi di launchd.

Ecco il file di avvio:

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

Ho salvato il file in ~/Library/LaunchAgents/com.mycron.hourly.pliste quindi lo ha caricato con:

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

Una volta caricato, verrà eseguito immediatamente e quindi nuovamente ogni 60 minuti.

Se segui la stessa procedura, ti consigliamo di cambiare la stringa `ProgramArguments 'con il percorso corretto per il tuo script.


2
Infatti, cron è deprecato almeno in Lion. Complimenti per aver trovato la risposta - launchctl può essere difficile da violare inizialmente.
zwerdlds

7

L'aggiunta del seguente codice allo script della shell bash risolverà il problema:

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

Sostituire your_user con il tuo nome utente.

Questo codice imposta il valore corretto per SSH_AUTH_SOCK che informa ssh o scp su come comunicare con ssh-agent quando viene avviato lo script della shell cron.


Questo ha risolto il problema che stavo vedendo dove scp non funzionava tramite launchd in uno script di shell nonostante funzionasse correttamente tramite la normale riga di comando (iTerm o Terminal). Suggerimento eccellente.
TJ Luoma

Solo per la cronaca, su El Capitan 10.11.2: zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov

1

Mi aspetterei una maggiore sicurezza come sandbox e le modifiche per spostare ulteriormente le cose a 64 bit causano un dolore inaspettato.

Non è una risposta, di per sé, ma launchd sta ricevendo tutto l'amore dalla mela in questi giorni.

Non risolve il problema con cron, ma è più stabile e più persone possono aiutarlo.


Molto bella rispondi lì . Grazie per averlo pubblicato.
bmike

1

Per chiunque lo trovi ora, cercando di farlo funzionare in El Capitan, e ancora riluttante a trasformare il tuo cron job su una riga in uno script di avvio, la risposta di Werner Antweiler funziona ancora, ma il percorso è cambiato. Il sotto ha funzionato per me:

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

NOTA : ricorda di sostituire your_user con il tuo nome utente!

Non mi permetterebbe di presentare questo come un commento sulla sua risposta in quanto mi manca la reputazione, ma non volevo lasciarla senza aggiornare questo dato che mi ha definitivamente aiutato a configurarlo.

Modificare: 30 marzo 2016

Dopo aver provato questo per un po ', ho bisogno di aggiungere che questo funziona solo dopo che l'agente è stato usato almeno una volta durante il login. L'avvio di una connessione ssh o l'esecuzione manuale di ssh-agent è sufficiente per farlo. È inoltre possibile utilizzare uno script di avvio se si desidera eseguirlo automaticamente. Ho creato un startup.sh che esegue solo ssh-agent e quindi ha utilizzato Script Editor per salvare un file .app con quanto segue e ha aggiunto l'app risultante ai miei elementi di accesso:

do shell script "/path/to/startup.sh"

Sto risolvendo questo adesso, e questo non è il modo migliore. apparentemente launchd è la strada da percorrere, ma per cron, si vuole impostare la chiave ssh (con passphrase) nel portachiavi. Una volta fatto ciò, l'accesso al Mac imposta tutto. Il percorso del socket che hai postato è dove vengono conservati se esegui ssh-agent manualmente (e inserisci manualmente la passphrase). Su El Cap, una volta caricato il portachiavi, cerca lo zoccolo tramite ls /private/tmp/com.apple.launchd.*/Listeners. Non devi fare nulla se non accedere a mac.
joe

launchd è sicuramente il modo "ufficiale" per farlo, ma per coloro che vogliono continuare ad usare cron, questo è utile come soluzione alternativa. Durante i miei test, il semplice accesso non era sufficiente per far funzionare una chiave salvata da un portachiavi tramite cron. Il percorso che hai elencato sicuramente esiste comunque. Se questo viene generato non appena si accede e funziona ancora per cron, è sufficiente essere in grado di saltare il metodo di script di avvio che ho elencato. Sicuramente vale la pena provare almeno - grazie!
Petie

Ho messo questo in atto per un processo di backup, ed è stato eseguito in modo pulito - attraverso i riavvii - per oltre una settimana.
joe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.