bash: użycie scp w zadaniu cron kończy się niepowodzeniem, ale działa poprawnie po uruchomieniu z wiersza poleceń

8

Próbuję użyć scp w skrypcie bash uruchamianym przez crona (uruchamiam to na Ubuntu 10.0.4 LTS).

Skrypt działa dobrze (tzn. Przesyła i kopiuje plik 1 i plik 2 do / ze zdalnego serwera, kiedy uruchamiam go z wiersza poleceń. Jednak gdy uruchamiam skrypt jako zadanie cron, nie działa.

Oto jak wygląda skrypt:

#!/bin/bash

cd /home/oompah/scripts/tests/
scp -P 12345 file1 oompah@someserver.com:~/uploads

if scp -P 12345 oompah@someserver.com:/path/to/file2.dat local.dat >&/dev/null ; then 
    echo "INFO: transfer OK" ; 
else 
    echo "ERROR: transfer failed" ; 
fi

Komunikat o błędzie, który otrzymuję (przekierowuję do pliku dziennika), gdy uruchamiam go jako zadanie CRON, to:

ERROR: transfer failed

Komunikat o błędzie wysyłany do mojej skrzynki odbiorczej to:

Permission denied (publickey).
lost connection

Dlaczego tak się dzieje i jak mogę to naprawić?

[Edytować]

Zmodyfikowałem pierwsze polecenie scp za pomocą polecenia -i (jak sugeruje M Jenkins), dodałem również -v dla komunikatów debugowania. Oto pełny dziennik komunikatów debugowania. Mamy nadzieję, że rzuci nieco światła na to, co się dzieje:

Executing: program /usr/bin/ssh host 12.34.56.78, user oompah, command scp -v -t ~/uploads
OpenSSH_5.3p1 Debian-3ubuntu6, OpenSSL 0.9.8k 25 Mar 2009
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to 12.34.56.78 [12.34.56.78] port 12345.
debug1: Connection established.
debug1: identity file /home/oompah/.ssh/id_rsa type 1
debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048
debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3p1 Debian-3ubuntu3
debug1: match: OpenSSH_5.3p1 Debian-3ubuntu3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.3p1 Debian-3ubuntu6
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host '[12.34.56.78]:12345' is known and matches the RSA host key.
debug1: Found key in /home/oompah/.ssh/known_hosts:3
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: /home/oompah/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug1: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: No more authentication methods to try.
Permission denied (publickey).
lost connection
Permission denied (publickey).
oompahloompah
źródło
3
Jakie wyniki otrzymujesz, jeśli nie przekierujesz stdout i stderr do / dev / null?
bmk
@bmk: bez przekierowania standardowego otrzymuję następujące komunikaty: Odmowa dostępu (publickey). utracone połączenie Odmowa dostępu (publickey).
oompahloompah
Sugestia: Nigdy nie odrzucaj stderr w takich skryptach. Jest to bardziej przydatne niż posiadanie pojedynczego komunikatu „ERROR”.
user1686,
1
może być tak, że a.) używasz agenta podczas interaktywnego uruchamiania polecenia, b.) uruchamiasz go jako inny użytkownik bez własnej pary kluczy (lub folderu domowego) lub c.), że klucze autoryzowane na celu ograniczają źródło połączenie ...?
0xC0000022L

Odpowiedzi:

7

Zgaduję że:

Posiadasz chronioną hasłem parę kluczy SSH, która jest automatycznie ładowana przez GNOME Keyring podczas logowania. Nie cronma jednak dostępu do kluczy i sshnie może poprosić o hasło (z powodu braku tty).

Aby zacytować sshdodany dziennik:

debug1: Oferowanie klucza publicznego : /home/oompah/.ssh/id_rsa
debug1: Serwer akceptuje klucz: pkalg ssh-rsa blen 277
debug1: PEM_ read_PrivateKey nie powiodło się
debug1: odczyt PEM prywatny klucz wykonany: wpisz
debug1: read_passphrase: nie można otworzyć / dev / tty : Brak takiego urządzenia lub adresu

użytkownik1686
źródło
@grawity: Dzięki za informację. Jak mogę rozwiązać problem?
oompahloompah
@oompah: Usuń hasło z pary kluczy. (Jeśli chcesz, możesz utworzyć drugi wyłącznie do zautomatyzowanego użytku i dać go scp -i.)
user1686,
@grawity: Dzięki za opinie. Nie czuję się dobrze usuwając hasło z mojego Keypair (w każdym razie nie wiedziałbym, jak to zrobić). Wspominasz o utworzeniu „drugiego” - przypuszczalnie masz na myśli drugą parę kluczy - ale tę bez hasła - więc mogę używać jej do automatycznych logowań. BTW, masz na myśli PASSPHRASE, kiedy mówisz hasło?
oompahloompah
@oompah: Jeśli twoja maszyna CentOS jest fizycznie bezpieczna, jest w porządku. Druga sugestia pary kluczy będzie prawdopodobnie przydatna tylko wtedy, gdy masz wiele kluczy kluczowych w wielu systemach. (OpenSSH nazywa to „hasłem”, ale niewiele osób faktycznie używa całej frazy do swoich kluczy.)
user1686
W końcu udało mi się to zadziałać, po mnóstwie przekręcania pęku kluczy itp. W końcu zdecydowałem się na twoją sugestię, aby stworzyć parę kluczy bez hasła dla crona i przekazać ją do scp w skrypcie powłoki. To nie powinno być naprawdę trudne ... SMH
oompahloompah
3

Wygląda na to, że scp nie odbiera pary kluczy publiczny / prywatny z katalogu ~ / .ssh.

Spróbuj dodać

HOME=/home/oompah

w górnej części pliku crontab (i tak powinno już być ustawione automatycznie)

Możesz także spróbować dodać

echo "DEBUG: My home dir is $HOME"

do skryptu, aby upewnić się, że uzyska odpowiednią wartość.

Inną opcją jest określenie parametru -i do scp, aby wymusić użycie określonej pary kluczy:

scp -i /home/oompah/.ssh/id_rsa ...

na przykład.

Majenko
źródło
Próbowałem twojej sugestii (używając opcji -i). Zobacz moje zaktualizowane pytanie
oompahloompah,
3

Jakiego użytkownika używa cron? Wygląda na to, że ten użytkownik nie ma dostępu do twojego klucza publicznego.

kwantowy
źródło
0

Chociaż nie jest to problemem w tym przypadku, cron interpretuje znak procentu ( %) jako znak nowej linii, więc należy go uciec ( \%), inaczej skończy się połowa polecenia, zastanawiającego się, dlaczego cron po prostu nic nie robi (chociaż narzeka w syslog).

Może to powodować problemy, jeśli pracujesz /bin/datew swoim crontabie.

Michał Trojanek
źródło