ssh-under-cron หยุดทำงานใน OS X 10.7 Lion


12

เพิ่งอัพเกรดจาก Snow Leopard เป็น Lion และงาน cron ของฉันที่ใช้ ssh หยุดทำงาน ปรากฏว่า ssh-agent ไม่ทำงานตามที่คาดไว้

ต่อไปนี้เป็นสคริปต์ที่เรียกว่าจาก cron รุ่นที่ใช้งานได้ดีซึ่งทำงานได้ดีภายใต้ 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

เมื่อเรียกใช้จากพรอมต์คำสั่งสคริปต์นี้ทำงานตามที่คาดไว้

เมื่อทำงานจาก cron มันไม่ทำงาน เอาต์พุต ssh-agent ดูปกติ:

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

แต่ssh -vvvผลลัพธ์แสดงว่ามันล้มเหลวทันทีเมื่ออ่านไพรเวตคีย์:

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

กล่าวอีกอย่างหนึ่งก็คือฉันคาดหวังให้พิมพ์ข้อความรหัสผ่านสำหรับ~/.ssh/id_dsaซึ่งแน่นอนว่าไม่สามารถใช้กับงาน cron ได้

ทั้งหมดนี้ทำงานใน Snow Leopard

โปรดทราบว่าฉันได้มีการติดตั้ง Keychain Access เพื่อให้ssh, ssh-agentและssh-addได้รับอนุญาตให้อ่านข้อความรหัสผ่านของฉันสำหรับฉัน.ssh/id_dsaไฟล์ - เป็นผลที่ฉันสามารถ SSH จากสถานีพร้อมรับคำโดยไม่ต้องใส่รหัสผ่านสำหรับการของฉัน

เป็นปัญหาที่ฉันต้องทำงานssh-addในบางช่วงของกระบวนการเข้าสู่ระบบของฉันหรือไม่ การเรียกใช้จากพรอมต์ bash มาตรฐานไม่ได้ช่วย cron job out (แม้ว่าแปลก ๆ มันทำให้ฉันใส่รหัสผ่านของฉัน ... ซึ่งฉันคิดว่าไม่จำเป็นต้อง b / c ของการกำหนดค่า Keychain Access)

หมายเหตุ 1 - ก่อนที่จะเปลี่ยนเส้นทางฉัน - ฉันรู้ว่ามีคำถามที่คล้ายกันที่นี่ ( Mac OS X Lion และ sshpass ) แต่เป็นเฉพาะเกี่ยวกับโปรแกรมsshpassที่ฉันไม่ได้ใช้ (แม้ว่าฉันเชื่อว่าคำถามนี้จะตอบโดยคนนี้เช่นกัน )

หมายเหตุ 2 - ฉันตระหนักว่าคีย์ SSH ที่ไม่มีข้อความรหัสผ่านจะแก้ปัญหาของฉันได้ แต่ฉันไม่ต้องการไปเส้นทางนี้


2
cron หายไป ดูแท็ก launchd ที่นี่สำหรับความช่วยเหลือทุกประเภท (ทำการย้าย - จัดการพอร์ตสิ่งแวดล้อมและอื่น ๆ อีกมากมายที่ดีกว่า cron ที่เคยทำ) - ฉันหวังว่าบางคนจะมีทางออก แต่ cron mojo ที่นี่มีอายุแน่นอน .
bmike

3
cron ยังคงทำงานใน Lion ... แต่คุณพูดถูกฉันควรทำอะไร ไฟล์ XML 10 บรรทัดที่ใช้ในการทำงานกับ LINE of crontab เดียวนั้นค่อนข้างง่อย บางทีใน 10 ปีพวกเขาจะเปลี่ยนไฟล์ plist เป็น JSON และจะมีความยินดีอย่างมากและ 10 ปีหลังจากนั้นพวกเขาจะกลับไปที่ crontab และ BSD greybeards จะหัวเราะ ฉันคิดว่าฉันจะเป็น greybeard BSD ด้วยแล้ว ...
จอห์นฮาร์ท

1
เพิ่งเปลี่ยนเป็น launchd ใช้งานได้อย่างมีเสน่ห์ สคริปต์ที่เรียกว่าไม่จำเป็นต้องโต้ตอบกับ ssh-agent เลย - คุณสามารถกระโดดเข้าไปในคำสั่ง ssh หลังจาก hashbang ได้ หากความคิดเห็นของคุณเป็นคำตอบฉันจะยอมรับมัน =)
John Hart

JSON ส่องสว่างมากกว่า XML ในหลายกรณีอย่างแน่นอน แต่บรรดาผู้วางแผนที่มาก่อนน่าจะบังคับให้เกิดปัญหา ฉันแค่รู้สึกว่าเรามีการเปลี่ยนโครงสร้างข้อมูลแบบครบวงจรที่มีประสิทธิภาพ cron และแน่นอนว่าเราทำหน้าที่ได้ดีสำหรับทุกวัย!
bmike

ฉันค้นหาทรัพยากรทางเว็บที่สูงและต่ำมากแล้ว แต่ท้ายที่สุดฉันก็กลับมาที่โพสต์นี้ แน่นอนว่าบางคนมีส่วนร่วมในการอภิปรายมากกว่านี้ใช่ไหม ฉันได้ลองใช้คำสั่งง่ายๆเพื่อรันเชลล์สคริปต์ แต่ mailx ไม่ส่งการแจ้งเตือนของฉัน ฉันยังคงชอบ cron และฉันใช้มันใน Ubuntu ตลอดเวลา ฉันไม่ต้องการกลับไปที่ 10.6 แต่ปัญหานี้กำลังฆ่าฉัน ฉันไม่ชอบถูกบังคับให้ใช้ Launchctl และต้องเรียนรู้ว่าฉันรู้สึกอย่างไรกับกรอบการทำงานที่กว้างใหญ่มากในการทำให้เชลล์สคริปต์เป็นแบบอัตโนมัติ ใครมีข้อมูลเชิงลึกใหม่บ้าง

คำตอบ:


10

สำหรับทุกคนที่ลงเอยในหน้านี้ฉันรู้ว่าฉันควรโพสต์คำตอบ:

การใช้ launchd แทน cron จะแก้ไขปัญหาการอนุญาตได้อย่างแน่นอน ผู้ใช้งาน launchd ของคุณ (ซึ่งทำงานเฉพาะเมื่อคุณลงชื่อเข้าใช้) ใช้ข้อมูลตัวแทน SSH ที่ถูกปลดล็อคผ่านทางพวงกุญแจของคุณเป็นส่วนหนึ่งของการเข้าสู่ระบบอย่างถูกต้อง (เป็นส่วนหนึ่งของการจัดการคีย์ OS X มาตรฐานโดยไม่ต้องใช้ซอฟต์แวร์อื่น ๆ )

เพื่อลดการโต้ตอบของฉันกับ launchd ฉันได้สร้างงาน launchd เดียวซึ่งเรียกสคริปต์ทุบตี ด้วยวิธีนี้ฉันสามารถแก้ไขสคริปต์โดยไม่ต้องเกี่ยวข้องกับ launchd

นี่คือไฟล์ 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>

ฉันบันทึกไฟล์ไปยัง~/Library/LaunchAgents/com.mycron.hourly.plistแล้วโหลดด้วย:

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

เมื่อโหลดแล้วมันจะวิ่งออกไปทันทีจากนั้นอีกครั้งทุกๆ 60 นาที

หากคุณทำตามขั้นตอนเดียวกันคุณจะต้องเปลี่ยนสตริง `ProgramArguments 'ด้วยพา ธ ที่ถูกต้องไปยังสคริปต์ของคุณ


2
แท้จริงแล้ว cron ถูกคัดค้านอย่างน้อยใน Lion รุ่งโรจน์สำหรับการค้นหาคำตอบ - launchctl อาจเป็นเรื่องยากที่จะบุกเข้าไปในตอนแรก
zwerdlds

7

การเพิ่มรหัสต่อไปนี้ลงใน bash shell script ของคุณจะแก้ไขปัญหาได้:

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

แทนที่your_userด้วยชื่อผู้ใช้ของคุณเอง

รหัสนี้จะตั้งค่าที่ถูกต้องสำหรับการSSH_AUTH_SOCKแจ้งว่าsshหรือscpเกี่ยวกับวิธีการสื่อสารกับเมื่อสคริปต์เชลล์จะเริ่มต้นจากssh-agentcron


สิ่งนี้แก้ปัญหาที่ฉันมีซึ่ง scp จะไม่ทำงานผ่าน launchd ในเชลล์สคริปต์แม้ว่ามันจะทำงานได้ดีผ่านบรรทัดคำสั่งปกติ (iTerm หรือ Terminal) เคล็ดลับที่ยอดเยี่ยม
TJ Luoma

เพียงเพื่อบันทึกบน El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov

1

ฉันคาดว่าการรักษาความปลอดภัยขั้นสูงเช่นแซนด์บ็อกซ์และการเปลี่ยนแปลงเพื่อย้ายสิ่งต่าง ๆ ไปยัง 64 บิตจะทำให้เกิดความเศร้าโศก

มันไม่ได้เป็นคำตอบต่อ แต่การเปิดตัวได้รับความรักจากแอปเปิ้ลทุกวันนี้

มันไม่ได้แก้ไขปัญหา cron แต่มีเสถียรภาพมากขึ้นเช่นเดียวกับผู้คนจำนวนมากสามารถช่วยได้


ดีมากคำตอบที่มี ขอบคุณสำหรับการโพสต์
bmike

1

สำหรับทุกคนที่พบสิ่งนี้พยายามที่จะทำให้งานนี้ใน El Capitan และยังลังเลที่จะเปลี่ยนงาน cron แบบบรรทัดเดียวของคุณให้เป็นสคริปต์เปิดตัวคำตอบของ Werner Antweiler ยังคงใช้ได้ แต่เส้นทางเปลี่ยนไป ด้านล่างใช้งานได้สำหรับฉัน:

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

หมายเหตุ : อย่าลืมแทนที่ your_user ด้วยชื่อผู้ใช้ของคุณ!

มันจะไม่ให้ฉันส่งสิ่งนี้เป็นความคิดเห็นในคำตอบของเขาเนื่องจากฉันขาดชื่อเสียง แต่ฉันไม่ต้องการจากเธอไปโดยที่ไม่ได้อัปเดตเพราะมันช่วยฉันได้ในที่สุด

แก้ไข: 30 มีนาคม 2559

หลังจากทดสอบมาระยะหนึ่งแล้วฉันต้องเพิ่มว่าจะใช้งานได้เฉพาะเมื่อมีการใช้ตัวแทนอย่างน้อยหนึ่งครั้งในระหว่างการเข้าสู่ระบบนั้น การเริ่มต้นการเชื่อมต่อ ssh หรือเรียกใช้ ssh-agent ด้วยตนเองก็เพียงพอที่จะทำ สามารถใช้สคริปต์เริ่มต้นได้หากคุณต้องการให้สคริปต์ทำงานโดยอัตโนมัติ ฉันสร้าง startup.sh ที่เพิ่งรัน ssh-agent จากนั้นใช้ Script Editor เพื่อบันทึก. app ด้วยต่อไปนี้และเพิ่มแอพที่เป็นผลลัพธ์ลงในรายการล็อกอินของฉัน:

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

ฉันกำลังแก้ปัญหาอยู่ตอนนี้และนี่ไม่ใช่วิธีที่ดีที่สุด เห็นได้ชัดว่า launchd เป็นวิธีที่จะไป แต่สำหรับ cron คุณต้องการตั้งค่าคีย์ ssh ของคุณ (ด้วยวลีรหัสผ่าน) ในพวงกุญแจของคุณ เมื่อคุณทำเสร็จแล้วเพียงเข้าสู่ระบบ Mac เพื่อตั้งค่าทุกอย่าง เส้นทางซ็อกเก็ตที่คุณโพสต์นั้นเป็นที่เก็บหากคุณใช้ ssh-agent ด้วยตนเอง (และพิมพ์ข้อความรหัสผ่านของคุณด้วยตนเอง) ต่อ El Cap ls /private/tmp/com.apple.launchd.*/Listenersเมื่อมีการโหลดพวงกุญแจหาซ็อกเก็ตผ่านทาง คุณไม่ต้องทำอะไรนอกจากลงชื่อเข้าใช้ mac
joe

launchd เป็นวิธีที่ "เป็นทางการ" อย่างแน่นอนที่จะทำ แต่สำหรับผู้ที่ต้องการใช้ cron ต่อไปสิ่งนี้จะเป็นวิธีแก้ปัญหาที่ทำงานได้ ในการทดสอบของฉันเพียงเข้าสู่ระบบไม่เพียงพอที่จะทำให้คีย์บันทึกพวงกุญแจทำงานผ่าน cron เส้นทางที่คุณระบุไว้นั้นมีอยู่จริง หากสิ่งนั้นถูกสร้างขึ้นทันทีที่คุณเข้าสู่ระบบและยังคงใช้งานได้สำหรับ cron อาจเป็นไปได้ที่จะข้ามวิธีการเริ่มต้นสคริปต์ที่ฉันแสดงไว้ การทดสอบที่คุ้มค่าอย่างน้อย - ขอบคุณ!
Petie

ฉันวางสิ่งนี้ไว้สำหรับกระบวนการสำรองข้อมูลและมันก็ทำงานได้อย่างสมบูรณ์ - ในการรีบูต - เป็นเวลากว่าหนึ่งสัปดาห์แล้ว
joe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.