ssh-under-cron przestaje działać w systemie OS X 10.7 Lion

12

Właśnie zaktualizowałem wersję Snow Leopard do Lion, a moje zadania cron używające ssh przestały działać. Wygląda na to, że ssh-agent nie działa już zgodnie z oczekiwaniami.

Oto pełna wersja mojego skryptu wywoływanego z crona, który świetnie działał w systemie 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

Po uruchomieniu z wiersza polecenia ten skrypt działa zgodnie z oczekiwaniami.

Po uruchomieniu z crona to nie działa. Dane wyjściowe ssh-agent wyglądają normalnie:

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

Ale dane ssh -vvvwyjściowe pokazują, że nie powiedzie się, gdy klucz prywatny powinien zostać odczytany:

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

Innymi słowy, oczekuje ode mnie wpisania hasła ~/.ssh/id_dsa, co oczywiście nie działa w zadaniach crona.

Wszystko to działało w Snow Leopard.

Zauważ, że mam konfigurację dostępu do pęku kluczy, dzięki czemu ssh, ssh-agenti ssh-addmogą czytać moje hasło do mojego .ssh/id_dsapliku - w wyniku mogę ssh z terminala szybka bez konieczności wprowadzić moje hasło.

Czy to problem, który muszę uruchomić ssh-addw pewnym momencie procesu logowania? Uruchomienie go ze standardowego monitu bash nie pomaga w wykonaniu zadania cron (chociaż, co dziwne, monituje mnie o moje hasło ... które moim zdaniem nie jest konieczne b / c konfiguracji dostępu do pęku kluczy).

UWAGA 1 - przed przekierowaniem mnie - wiem, że jest tutaj podobne pytanie ( Mac OS X Lion i sshpass ), ale dotyczy ono konkretnie programu sshpass, którego nie używam (chociaż wierzę, że na to pytanie również odpowiem ).

UWAGA 2 - Zdaję sobie sprawę, że klucze SSH bez hasła mogłyby rozwiązać mój problem; jednak wolałbym nie iść tą drogą.

John Hart
źródło
2
cron zniknął. Zobacz znacznik uruchomieniowy tutaj, aby uzyskać wszelkiego rodzaju pomoc (zrób ruch - obsługuje porty, środowisko i wiele, wiele więcej, niż kiedykolwiek cron kiedykolwiek) - Mam nadzieję, że ktoś ma rozwiązanie, ale cron mojo tutaj z pewnością się starzeje .
bmike
3
cron nadal działa w Lwie ... ale masz rację, powinienem wykonać ruch. 10-liniowy plik XML do wykonania pojedynczej linii wiersza crontab jest jednak dość kiepski. Może za 10 lat zmienią pliki z listami na JSON i będzie dużo radości, a po 10 latach wrócą do crontab, a siwobrody BSD będą się śmiać. Przypuszczam, że do tego czasu będę siwobrodym BSD ...
John Hart,
1
Właśnie przełączono na uruchomienie, działa jak urok. Wywoływany skrypt wcale nie musi wchodzić w interakcje z ssh-agent - możesz po prostu przejść bezpośrednio do polecenia ssh po haszowaniu. Gdyby twój komentarz był odpowiedzią, zaakceptowałbym go =)
John Hart
JSON z pewnością świeci nad XML w wielu przypadkach, ale wszystkie wcześniejsze listy prawdopodobnie wymusiły ten problem. Jestem po prostu łaskotany, że mamy ujednoliconą, wydajną, ustrukturyzowaną wymianę opartą na danych. cron i na pewno służył nam dobrze przez wieki!
bmike
Szukałem wysoko i nisko dodatkowych zasobów internetowych, ale zawsze wracam do tego postu. Z pewnością ktoś może wnieść coś więcej do dyskusji? Próbowałem użyć prostego narzędzia do uruchamiania skryptu powłoki, ale mailx nie wysyła moich powiadomień. Nadal lubię crona i cały czas używam go w Ubuntu. Nie chcę wracać do wersji 10.6, ale ten problem mnie zabija. Nie lubię zmuszania mnie do używania launchctl i konieczności uczenia się, co wydaje mi się bardzo rozbudowanym frameworkiem do automatyzacji skryptów powłoki. Czy ktoś ma jakieś nowe informacje?

Odpowiedzi:

10

Dla każdego, kto trafi na tę stronę, zrozumiałem, że powinienem opublikować odpowiedź:

Użycie launchd zamiast crona rzeczywiście rozwiązuje problem z autoryzacją. Zadania uruchamiane przez użytkownika (uruchamiane tylko po zalogowaniu) poprawnie wykorzystują informacje agenta SSH, które zostały odblokowane za pomocą pęku kluczy w ramach logowania (w ramach standardowego zarządzania kluczami OS X, żadne inne oprogramowanie nie jest wymagane).

Aby zminimalizować interakcje z uruchomionym programem, stworzyłem jedno uruchomione zadanie, które wywołuje skrypt bash. W ten sposób mogę po prostu edytować skrypt bez zajmowania się uruchomionym.

Oto uruchomiony plik:

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

Zapisałem plik ~/Library/LaunchAgents/com.mycron.hourly.plist, a następnie załadowałem go:

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

Po załadowaniu będzie działać od razu, a następnie co 60 minut.

Jeśli zastosujesz tę samą procedurę, będziesz chciał zmienić ciąg `ProgramArguments ', podając właściwą ścieżkę do skryptu.

John Hart
źródło
2
Rzeczywiście, cron jest przestarzały przynajmniej w Lion. Uznanie za znalezienie odpowiedzi - początkowo może być trudno włamać się na launchctl.
zwerdlds
7

Dodanie następującego kodu do skryptu powłoki bash rozwiąże problem:

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

Zastąp your_userswoją własną nazwą użytkownika.

Ten kod ustawia poprawną wartość SSH_AUTH_SOCKinformującą sshlub scpo tym, jak się komunikować, ssh-agentkiedy skrypt powłoki zostanie uruchomiony cron.

Werner Antweiler
źródło
To rozwiązało problem, w którym miałem problem z tym, że scp nie działał przez uruchomienie w skrypcie powłoki, mimo że działał dobrze w zwykłym wierszu poleceń (iTerm lub Terminal). Doskonała wskazówka.
TJ Luoma,
Dla przypomnienia, w El Captain 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov
1

Spodziewałbym się, że zwiększone bezpieczeństwo, takie jak piaskownica i zmiany, które pozwolą na dalsze przenoszenie rzeczy do wersji 64-bitowej, powodują nieoczekiwany ból.

Nie jest to odpowiedź sama w sobie, ale premiera zyskuje obecnie całą miłość z jabłek.

Nie rozwiązuje to problemu z cronem, ale jest bardziej stabilny, a więcej osób może w tym pomóc.

bmike
źródło
Bardzo miła odpowiedź . Dzięki za opublikowanie.
bmike
1

Dla każdego, kto znajdzie to teraz, próbując sprawić, by działało to w El Capitan, i nadal niechętnie zmienia jedno-liniowe zadanie crona w uruchomiony skrypt, odpowiedź Wernera Antweilera nadal działa, ale ścieżka się zmieniła. Poniższe działało dla mnie:

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

UWAGA : pamiętaj o zastąpieniu twojego_użytkownika swoją nazwą użytkownika!

Nie pozwoliłbym przesłać tego jako komentarza do jego odpowiedzi, ponieważ brakuje mi reputacji, ale nie chciałem jej zostawiać bez aktualizacji, ponieważ zdecydowanie pomogło mi to ostatecznie skonfigurować.

Edycja: 30 marca 2016 r

Po przetestowaniu tego przez chwilę muszę dodać, że działa to tylko wtedy, gdy agent został użyty przynajmniej raz podczas logowania. Wystarczy zainicjować połączenie ssh lub ręcznie uruchomić ssh-agent. Można także użyć skryptu uruchamiania, jeśli chcesz, aby był uruchamiany automatycznie. Utworzyłem startup.sh, który właśnie uruchamia ssh-agent, a następnie użyłem Edytora skryptów, aby zapisać .app z następującymi i dodałem wynikową aplikację do moich elementów logowania:

do shell script "/path/to/startup.sh"
Petie
źródło
Rozwiązuję to teraz i nie jest to najlepszy sposób. uruchamianie najwyraźniej jest właściwą drogą, ale dla crona chcesz ustawić swój klucz ssh (z hasłem) w swoim pęku kluczy. Gdy to zrobisz, wystarczy zalogować się do komputera Mac, aby wszystko skonfigurować. Ścieżka gniazda, którą opublikowałeś, jest tam, gdzie są przechowywane, jeśli ręcznie uruchomisz ssh-agent (i ręcznie wpisujesz hasło). Na El Cap po załadowaniu pęku kluczy znajdź gniazdo przez ls /private/tmp/com.apple.launchd.*/Listeners. Nie musisz nic robić poza logowaniem do systemu Mac.
Joe
uruchomienie zdecydowanie jest „oficjalnym” sposobem na zrobienie tego, ale dla tych, którzy chcą nadal używać crona, służy to jako realne obejście. W moich testach samo zalogowanie nie wystarczyło, aby klucz zapisany w pęku kluczy działał przez crona. Wymieniona ścieżka zdecydowanie jednak istnieje. Jeśli zostanie wygenerowany, gdy tylko się zalogujesz i nadal działa dla crona, prawdopodobnie wystarczy pominąć metodę skryptu uruchamiania, którą wymieniłem. Z pewnością warto przynajmniej przetestować - dzięki!
Petie
Umieściłem to na potrzeby procesu tworzenia kopii zapasowej i działa on płynnie - po ponownym uruchomieniu - od ponad tygodnia.
Joe