ssh-under-cron berhenti bekerja di OS X 10.7 Lion

12

Baru saja ditingkatkan dari Snow Leopard ke Lion, dan pekerjaan cron saya yang menggunakan ssh telah berhenti bekerja. Tampaknya ssh-agent tidak lagi berfungsi seperti yang diharapkan.

Berikut ini adalah versi singkat dari skrip dipanggil-dari-cron saya yang bekerja sangat baik di bawah 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

Saat dijalankan dari prompt perintah, skrip ini berfungsi seperti yang diharapkan.

Ketika dijalankan dari cron, itu tidak bekerja. Output ssh-agent terlihat normal:

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

Tetapi ssh -vvvoutput menunjukkan bahwa gagal tepat ketika kunci pribadi harus dibaca:

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

Dengan kata lain, itu mengharapkan saya untuk mengetikkan frasa sandi ~/.ssh/id_dsa, yang tentu saja tidak berfungsi dalam pekerjaan cron.

Ini semua bekerja di Snow Leopard.

Perhatikan bahwa saya punya pengaturan Keychain Access sehingga ssh, ssh-agent, dan ssh-adddiperbolehkan untuk membaca passphrase saya untuk saya .ssh/id_dsaberkas - sebagai hasilnya saya bisa SSH dari prompt terminal tanpa harus memasukkan kata sandi saya.

Apakah masalah ini yang perlu saya jalankan ssh-adddi beberapa titik dalam proses login saya? Menjalankannya dari bash prompt standar tidak membantu pekerjaan cron (walaupun, anehnya, itu meminta saya untuk frasa sandi saya ... yang saya pikir tidak perlu b / c dari konfigurasi Akses Keychain).

CATATAN 1 - sebelum mengarahkan saya - Saya sadar ada pertanyaan serupa di sini ( Mac OS X Lion dan sshpass ) tetapi ini secara khusus tentang program sshpassyang tidak saya gunakan (walaupun saya percaya pertanyaan itu akan dijawab oleh yang satu ini juga ).

CATATAN 2 - Saya menyadari bahwa kunci SSH tanpa frasa sandi akan menyelesaikan masalah saya; namun saya lebih suka untuk tidak menempuh rute ini.

John Hart
sumber
2
cron hilang. Lihat tag launchd di sini untuk segala macam bantuan (lakukan langkah - ini menangani port, lingkungan, dan jauh lebih baik daripada yang pernah dilakukan cron) - Saya berharap ada yang punya solusi, tapi cron mojo di sini menua pasti .
bmike
3
cron masih berjalan di Lion ... tapi kau benar, aku harus bergerak. File XML 10+ baris untuk melakukan pekerjaan satu LINE crontab memang cukup lemah. Mungkin dalam 10 tahun mereka akan beralih file plist ke JSON, dan akan ada banyak kesenangan, dan 10 tahun setelah itu mereka akan kembali ke crontab, dan para greybeards BSD akan tertawa. Saya kira saya akan menjadi greybeard BSD pada saat itu ...
John Hart
1
Baru saja beralih ke launchd, bekerja dengan sangat baik. Skrip yang dipanggil tidak perlu berinteraksi dengan ssh-agent sama sekali - Anda bisa langsung beralih ke perintah ssh setelah hashbang. Jika komentar Anda adalah jawaban, saya akan menerimanya =)
John Hart
JSON tentu saja bersinar dalam XML dalam banyak kasus, tetapi semua daftar yang muncul sebelumnya kemungkinan besar memaksa masalah ini. Saya hanya tergelitik karena kami memiliki penggantian berbasis data yang terpadu, efisien, terstruktur. cron dan tentu melayani kami dengan baik selama berabad-abad!
bmike
Saya telah mencari tinggi dan rendah untuk sumber daya web tambahan tetapi saya selalu berakhir kembali pada posting ini. Tentunya seseorang memiliki kontribusi lebih untuk diskusi? Saya telah mencoba menggunakan plist sederhana untuk menjalankan skrip shell saya tetapi kemudian mailx tidak mengirimkan pemberitahuan saya. Saya masih suka cron dan saya menggunakannya di Ubuntu sepanjang waktu. Saya tidak ingin kembali ke 10.6 tetapi masalah ini membunuh saya. Saya tidak suka dipaksa menggunakan launchctl dan harus belajar apa yang terasa bagi saya seperti kerangka kerja yang sangat luas untuk mengotomatisasi skrip shell pada dasarnya. Adakah yang memiliki wawasan baru?

Jawaban:

10

Bagi siapa pun yang berakhir di halaman ini, saya menyadari saya harus memposting jawabannya:

Menggunakan launchd bukannya cron memang memperbaiki masalah otorisasi. Pengguna Anda meluncurkan pekerjaan (yang dijalankan hanya ketika Anda masuk) dengan benar menggunakan informasi agen SSH yang dibuka melalui gantungan kunci Anda sebagai bagian dari login (sebagai bagian dari manajemen kunci standar OS X, tidak ada perangkat lunak lain yang diperlukan).

Untuk meminimalkan interaksi saya dengan launchd, saya membuat satu pekerjaan launchd yang memanggil skrip bash. Dengan cara ini saya cukup mengedit skrip tanpa berurusan dengan launchd.

Inilah file 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>

Saya menyimpan file ke ~/Library/LaunchAgents/com.mycron.hourly.plist, dan kemudian memuatnya dengan:

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

Setelah dimuat, itu akan berjalan segera dan sekali lagi setiap 60 menit.

Jika Anda mengikuti prosedur yang sama, Anda ingin mengubah string `ProgramArguments 'dengan jalur yang benar ke skrip Anda.

John Hart
sumber
2
Memang, cron sudah tidak digunakan lagi di Lion. Kudos untuk menemukan jawabannya - launchctl mungkin sulit untuk dibobol pada awalnya.
zwerdlds
7

Menambahkan kode berikut ke skrip bash shell Anda akan memperbaiki masalahnya:

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

Ganti your_userdengan nama pengguna Anda sendiri.

Kode ini menetapkan nilai yang benar untuk SSH_AUTH_SOCKyang menginformasikan sshatau scptentang bagaimana berkomunikasi dengan ssh-agentketika skrip shell dimulai cron.

Werner Antweiler
sumber
Ini memecahkan masalah yang saya alami di mana scp tidak akan bekerja melalui launchd dalam skrip shell meskipun berfungsi dengan baik melalui baris perintah biasa (iTerm atau Terminal). Tip yang luar biasa.
TJ Luoma
Sebagai catatan, pada El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov
1

Saya berharap keamanan yang ditingkatkan seperti kotak pasir dan perubahan untuk memindahkan lebih jauh ke 64 bit menyebabkan kesedihan yang tak terduga.

Itu bukan jawaban, per se, tetapi launchd mendapatkan semua cinta dari apel hari ini.

Ini tidak memperbaiki masalah cron, tetapi lebih stabil serta lebih banyak orang dapat membantu.

bmike
sumber
Jawabannya sangat bagus . Terima kasih telah mempostingnya.
bmike
1

Bagi siapa pun yang menemukan ini sekarang, mencoba membuat ini bekerja di El Capitan, dan masih enggan mengubah pekerjaan cron satu baris Anda menjadi skrip launchd, jawaban Werner Antweiler masih berfungsi tetapi jalurnya berubah. Di bawah ini bekerja untuk saya:

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

CATATAN : ingatlah untuk mengganti pengguna_Anda dengan nama pengguna Anda!

Itu tidak akan membiarkan saya mengirimkan ini sebagai komentar pada jawabannya karena saya tidak memiliki reputasi tetapi saya tidak ingin meninggalkannya tanpa memperbarui ini karena pasti membantu saya akhirnya mengaturnya.

Sunting: 30 Maret 2016

Setelah menguji ini sebentar, saya perlu menambahkan bahwa ini hanya berfungsi setelah agen telah digunakan setidaknya satu kali selama login itu. Memulai koneksi ssh atau menjalankan ssh-agent secara manual sudah cukup untuk melakukannya. Skrip startup juga dapat digunakan jika Anda ingin menjalankannya secara otomatis. Saya membuat startup.sh yang baru saja menjalankan ssh-agent dan kemudian menggunakan Script Editor untuk menyimpan .app dengan yang berikut ini dan menambahkan aplikasi yang dihasilkan ke item login saya:

do shell script "/path/to/startup.sh"
Petie
sumber
Saya sedang memecahkan ini sekarang, dan ini bukan cara terbaik. launchd tampaknya adalah cara untuk pergi, tetapi untuk cron, Anda ingin mengatur kunci ssh Anda (dengan frasa sandi) di gantungan kunci Anda. Setelah Anda selesai melakukannya, masuk saja ke Mac mengatur semuanya. Jalur soket yang Anda poskan adalah tempat mereka disimpan jika ANDA menjalankan ssh-agent secara manual (dan ketik frasa sandi Anda secara manual). Pada El Cap, setelah gantungan kunci dimuat, temukan soketnya melalui ls /private/tmp/com.apple.launchd.*/Listeners. Anda tidak perlu melakukan apa pun kecuali login ke mac.
joe
launchd jelas merupakan cara "resmi" untuk melakukannya tetapi bagi mereka yang ingin terus menggunakan cron, ini memang berfungsi sebagai solusi yang layak. Dalam pengujian saya, cukup masuk tidak cukup untuk menyebabkan kunci yang disimpan dengan gantungan kunci berfungsi melalui cron. Jalan yang Anda daftarkan pasti ada. Jika itu dihasilkan segera setelah Anda masuk dan masih bekerja untuk cron, kemungkinan sudah cukup untuk dapat melewati metode skrip startup yang saya daftarkan. Setidaknya layak untuk diuji - terima kasih!
Petie
Saya menempatkan ini di tempat untuk proses pencadangan, dan sudah berjalan bersih - di seluruh reboot - selama lebih dari seminggu sekarang.
joe