Dlaczego to zadanie rsync + ssh cron powoduje błędy „Odmowa zezwolenia (publickey)”?

20

Często wykonuję kopie zapasowe na dysku lokalnym, który chcę codziennie synchronizować ze zdalnym serwerem.

Serwer docelowy jest skonfigurowany tylko dla dostępu SSH (bez hasła). Ponieważ mój podstawowy klucz SSH dla tego serwera jest chroniony hasłem, stworzyłem drugi klucz SSH (nie chroniony hasłem) + użytkownika do użycia w przypadku nienadzorowanych kopii zapasowych - w ten sposób nie muszę być obecny, aby wprowadzić moje hasło po uruchomieniu crona .

Używam cron i rsync, a wszystkie polecenia działają indywidualnie, ale nie działają w połączeniu.

Najdalszy zasięg, jaki mam podczas rozwiązywania problemów, jest uruchomiony

env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"

co zwraca błąd

Permission denied (publickey).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(226) [sender=3.1.0]

Wszelkie wskazówki dotyczące dalszego rozwiązywania tego problemu?


Oto, co próbowałem do tej pory i nie mam pomysłów:

  1. Cron na pewno działa ps aux | grep cron
  2. Nic niezwykłego w / var / log / syslog Sep 7 13:22:01 desktop CRON[6735]: (tom) CMD (sh /home/tom/Documents/Scripts/offsite-backup)

  3. SSH w terminalu do zdalnego serwera, gdy działa użytkownik kopii zapasowej ssh [email protected]

  4. Uruchomienie polecenia w Terminalu działa idealnie rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
  5. Ręczne określenie ścieżki do klucza użytkownika kopii zapasowych nie ma wpływu rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/

  6. Działa zastąpienie niedziałającego polecenia prostym poleceniem testowym echo "Hello world" > ~/Desktop/test.txt

  7. Krzyki / przekleństwa przy komputerze nie przyniosły żadnego efektu (ale chwilowo poczułem się lepiej).


Edycja 1:

Oto mój plik crontab i skrypt, który wywołuje.

...
# m h  dom mon dow   command
MAILTO=""
* * * * * sh /home/tom/Documents/Scripts/offsite-backup

i

#!/bin/bash

rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/

Edycja 2:

Dla wyjaśnienia, /var/log/auth.logna serwerze docelowym zawiera wiersz Sep 11 08:23:01 <hostname> CRON[24421]: pam_unix(cron:session): session closed for user rootTo jest mylące, ponieważ nie uruchamiam już crona co minutę lokalnie, ale nowa pozycja wciąż pojawia się co minutę w logach serwera. Pliki Crontab dla wszystkich użytkowników (w tym root) na serwerze są puste i nic nie robią.

Ponadto użytkownik „tylko kopie zapasowe” został utworzony tylko na serwerze i z ograniczonymi prawami, z dedykowanym kluczem SSH skopiowanym na mój komputer. Zakładam, że jest to właściwa droga, ponieważ wszystko działa podczas ręcznego uruchamiania poleceń.

Plik crontab opublikowany powyżej jest dla mnie, użytkownika „tom” na moim komputerze stacjonarnym. Moim zamiarem jest wywołanie skryptu, który powinien zalogować się na serwerze jako użytkownik „tylko do tworzenia kopii zapasowych”. Właśnie próbowałem uruchomić skrypt kopii zapasowej (zamiast polecenia w nim zawartego) i udało mi się to połączyć i zadziałać. Uruchomiłem go na pulpicie jako użytkownik „tom”, ten sam użytkownik, który utworzył zadanie cron, które nie będzie działać. Oto dane wyjściowe z dziennika serwera odpowiadające udanemu logowaniu

Sep 11 08:35:31 <hostname> sshd[25071]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
Sep 11 08:35:32 <hostname> sshd[25071]: Accepted publickey for backups-only from <desktop IP> port 54242 ssh2: RSA e2:e6:07:27:c1:continues...
Sep 11 08:35:32 <hostname> sshd[25071]: pam_unix(sshd:session): session opened for user backups-only by (uid=0)
Sep 11 08:35:32 <hostname> systemd-logind[638]: New session 12 of user backups-only.
Sep 11 08:36:00 <hostname> sshd[25133]: Received disconnect from <desktop IP>: 11: disconnected by user
Sep 11 08:36:00 <hostname> sshd[25071]: pam_unix(sshd:session): session closed for user backups-only
Tom Brossman
źródło
Jeśli 3. działa przy użyciu pliku klucza, a 6. działa również, to ... err ... co mówi plik dziennika sshd po stronie odbierającej?
stycznia
@Jan otrzymujęSep 7 14:45:01 <hostname> CRON[18716]: pam_unix(cron:session): session closed for user root
Tom Brossman
To albo niewłaściwy wiersz dziennika, albo użytkownik próbujący połączyć się przez ssh to root ... A może to z komputera, który inicjuje tworzenie kopii zapasowych?
stycznia
1
Tom, 2 pytania, aby się upewnić. W pierwszym komentarzu linia logiczna ma CRON [...], ale powinno to wyglądać Sep 7 16:06:02 <hostname> sshd[6747].... Czy jesteś w 100% przekonany, że ta linia logiczna pochodzi z serwera i że jest to poprawna linia? Crontab, który opublikowałeś, to crontab tylko kopii zapasowych ? Spróbuj też dodać plik tożsamości ręcznie:rsync .... -e 'ssh -i /home/user/.ssh/identity' ...
Jan
1
Również ten wiersz w auth.logtobie opublikowany w Edycji 2 dotyczy crona działającego na serwerze i nie powinien mieć nic wspólnego z próbami logowania. Czy możesz spróbować tail -f /var/log/auth.logna serwerze, gdy próbujesz uruchomić skrypt przez crona? Nie jestem też pewien, czy to zadziała, ale czy możesz wypróbować swoje pierwsze envpolecenie, rsync .... -e 'ssh -vvv -i /home/user/.ssh/identity ...aby sprawdzić, czy to wyrzuca więcej błędów?
Alaa Ali,

Odpowiedzi:

15

Ponieważ wszystko działa poprawnie z wiersza polecenia, błąd Permission denied (publickey)oznacza, że ​​część SSH rsyncużywa innego pliku tożsamości niż określona nazwa użytkownika.

Na podstawie komentarza Jana do pierwotnego pytania możemy określić plik tożsamości w rsyncpoleceniu za pomocą -e 'ssh -i /path/to/identity.file' ....

Użycie poniższego polecenia, aby rozpocząć od nowego środowiska w cronie, i podanie pełnej ścieżki do pliku najwyraźniej rozwiązuje problem:

env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"

Nadal jestem bardzo zainteresowany tym odkryciem. Prawdopodobnie ma to związek z cronem, faktem, że zaczyna się od minimalnych zmiennych środowiskowych i ssh-agent. Przygotuję ten sam scenariusz za kilka dni, aby go przetestować i zgłosić.

Alaa Ali
źródło
1
Czy masz na myśli, że env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /path/to/identity.file' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"
uciekłeś
@Problemania Whops, naprawione.
Alaa Ali,
Widzę, że masz odpowiedź, ale jestem ciekawy, czy używasz „sudo crontab -e”, czyli root cron. Co się stanie, jeśli „crontab -e” zalogowany jako użytkownik „kopii zapasowej”.
wlraider70,
Myślę, że miałeś na myśli to dla osoby, która zadała pytanie. Ale używał crontab swojej nazwy użytkownika, a nie roota i myślę, że nie chciał używać crontaba użytkownika kopii zapasowej.
Alaa Ali,
kiedy uruchamiam podobny skrypt z moim użytkownikiem, pobiera on klucz ssh przez X11, więc potrzebowałem lokalnej kopii if key i upewnij się, że ten plik ma poprawnego właściciela i uprawnienia, w połączeniu z powyższym działał dobrze dla mnie.
Sverre
1

Właśnie rozwiązałem ten problem, który był zajęty.

Nie można połączyć się w RSYNC przez SSH, mimo że określono tożsamość dla SSH ... Nic się nie dzieje ... Rsync mówi „odmowa uprawnień”, a ssh mówi mi „read_passphrase: nie można otworzyć / dev / tty: Brak urządzenia lub adresu ten typ"

Ale przeczytałem post, który wyjaśnił, że crontab ma swoje własne środowisko, które nie jest tym samym co root. Już to wiedziałem, ale nie rozumiałem wpływu, jaki może to mieć na SSH podczas korzystania z SSH-AGENT

Ale moja wymiana kluczy SSH odbywa się za pomocą PassPhrase ... więc jeśli środowisko jest inne, a mój RSYNC przez SSH oczekuje hasła, którego nie można wprowadzić => Informacje o debugowaniu SSH również wskazują błąd:

„debug1: read_passphrase: nie można otworzyć / dev / tty: Brak takiego urządzenia lub adresu” => Cóż tak nie TTY = brak hasła = niedozwolone

Na moim komputerze używam „pęku kluczy”, aby uruchomić agenta SSH, więc nie muszę ponownie wpisywać hasła za każdym razem, gdy próbuję nawiązać połączenie zdalne. Keychain generuje plik zawierający następujące informacje

SSH_AUTH_SOCK = /tmp/ssh-PWg3yHAARGmP/agent.18891; eksport SSH_AUTH_SOCK; SSH_AGENT_PID = 18893; eksport SSH_AGENT_PID;

==> Komenda SSH-AGENT zwraca te same informacje.

Tak więc ostatecznie te informacje związane z bieżącą sesją umożliwiają przyszłe uwierzytelnienia bieżącej sesji, bez konieczności wprowadzania hasła, ponieważ zostało to już zrobione wcześniej i zapamiętane ...

==> Rozwiązanie już istnieje ... wystarczy w skrypcie uruchomionym przez crontab i „źródło” pliku zawierającego te informacje lub zrobić to w wierszu poleceń ds crontab ...

przykład: 14 09 * * *. /home/foo/.keychain/foo.serveur.org-sh && scp -vvv -P 22 /tmp/mon_fic/toto.sh [email protected]:. >> / var / log / check_connexion.log 2> & 1 lub użyj polecenia „source /home/foo/keychain/foo.server.org-sh” w skrypcie uruchamiającym połączenie za pomocą SSH.

=> Dzięki temu pozyskiwaniu nie musisz się już martwić. Informacje SSH_AUTH_SOCK i SSH_AGENT_PID są ładowane w środowisku Crontab i dlatego są znane, RSYNC przez SSH działa bez problemu.

To mnie zajęło, ale teraz działa :)

SoniXtrA
źródło
1

Zastrzeżenie dla tych, którzy korzystają z SSH Agent Forwarding:

Jeśli zobaczysz to zachowanie podczas debugowania skryptu na zdalnym hoście, to dlatego, że nawet z -e "ssh -i /path/to/key"flagą, ssh użyje twojego lokalnego (przekazanego) klucza zamiast klucza na serwerze.

Konkretny przykład: mam skrypt na serwerze deweloperskim, który pobiera dane z „serwera danych” za pomocą rsync przez ssh. Kiedy loguję się na serwerze deweloperskim i uruchamiam go, wszystko jest w porządku, ale podczas uruchamiania z crona dostaję odmowę dostępu. Dodając trochę gadatliwości do procesu SSH (flaga -vv) zauważyłem, co następuje:

debug2: key: /home/nighty/.ssh/id_rsa (0x562d8b974820),
debug2: key: /home/juanr/.ssh/id_rsa (0x562d8b962930), explicit
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/nighty/.ssh/id_rsa
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp 1a:19:08:9f:80:16:b1:db:55:42:9a:52:b2:49:9b:0a
debug1: Authentication succeeded (publickey).

To, co mnie oszukało, to fakt, że przypadkiem mam inną nazwę użytkownika na lokalnym hoście („prawie”) niż na serwerze deweloperskim („juanr”).

Zauważ, jak zaznacza klucz na serwerze deweloperskim jako „jawny”, ale nadal używa zalogowanego klucza z mojego laptopa do zalogowania się. Wykonanie ssh-copy-idw tym momencie niczego nie rozwiązuje, ponieważ po prostu przywraca przekazany klucz, a nie klucz od dewelopera serwer. Jeśli używasz ssh-copy-id ze spedycji agenta, trzeba określić, który klucz zainstalować z flagą -i: ssh-copy-id -i ~/.ssh/id_rsa.pub user@host.

jrial
źródło
0

Czy próbowałeś już starej sztuczki czyszczenia plików hostów? Mam na myśli:

rm ~/.ssh/known_hosts

Warto spróbować, ponieważ ssh go odbuduje, a pozbędziesz się przestarzałych rzeczy. Możesz oczywiście również usunąć części należące do danego adresu IP / hosta.

Więcej pytań: czy Twoje zadanie cron działa pod Twoim identyfikatorem UID, czy działa jako cron użytkownika lub root?

runlevel0
źródło
1
Każde z poleceń działa osobno, więc nie widzę, jak usunięcie ~/.ssh/known_hostsmogłoby coś zmienić? A cron działa jako mój użytkownik „tom” na pulpicie, z zamiarem zalogowania się na serwerze jako użytkownik „tylko do tworzenia kopii zapasowych” przy użyciu odpowiedniego (bez hasła) klucza SSH, który znajduje się w tomie użytkownika ~/.ssh.
Tom Brossman
3
@ runlevel0 Ani flaga -rani nie -fjest wymagana do usunięcia known_hosts- to zwykły plik (nie katalog) i nie jest on przeznaczony tylko do odczytu. rm .ssh/known-hostsbyłoby znacznie bezpieczniejsze, biorąc pod uwagę, że literówka jednoznakowa - przypadkowe dodanie spacji między .i ssh/known_hostspo rm -rf(lub rm -r) zwykle usuwa całą zawartość folderu domowego użytkownika!
Eliah Kagan
Cześć Eliah, naprawdę doskonały punkt !! Używam flagi -rf jako działania odruchowego, ale masz całkowitą rację. Ja źle
runlevel0
0

Użyj rrsyncskryptu razem z dedykowanym kluczem ssh w następujący sposób:

Zdalny serwer

mkdir ~/bin
gunzip /usr/share/doc/rsync/scripts/rrsync.gz -c > ~/bin/rrsync
chmod +x ~/bin/rrsync

LOKALNY komputer

ssh-keygen -f ~/.ssh/id_remote_backup -C "Automated remote backup"      #NO passphrase
scp ~/.ssh/id_remote_backup.pub [email protected]:/home/devel/.ssh

Komputer zdalny

cat id_remote_backup.pub >> authorized_keys

Wstaw do nowo dodanej linii następujące

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding

Tak wygląda wynik

command="$HOME/bin/rrsync -ro ~/backups/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAA...vp Automated remote backup

LOKALNY

Wprowadź crontabnastępujący skrypt za xzgodą:

#!/bin/sh
echo ""
echo ""
echo "CRON:" `date`
set -xv
rsync -e "ssh -i $HOME/.ssh/id_remote_backup" -avzP [email protected]:/ /home/user/servidor 

Źródło: http://www.guyrutenberg.com/2014/01/14/restricting-ssh-access-to-rsync/

Alessandro Cuttin
źródło
0

Aby spróbować debugować, dodaj do części ssh „ssh -v” w ten sposób możesz uzyskać pełny tryb z kilkoma przydatnymi informacjami.

Edycja: Ze strony podręcznika:

-v      Verbose mode.  Causes ssh to print debugging messages about its progress.  This is helpful in debugging connection,
             authentication, and configuration problems.  Multiple -v options increase the verbosity.  The maximum is 3.
Pedro Luz
źródło
-1

Myślę, że nie skonfigurowałeś poprawnie pliku sshd_config. Sprawdź to PermitRootLogin yesi PubkeyAuthentication yes do zdalnej konserwacji.

Anandu M Das
źródło
1
Nie próbuje się zalogować jako root i prawdopodobnie poprawnie skonfigurował uwierzytelnianie za pomocą klucza publicznego, ponieważ może ssh, a nawet pomyślnie wykonać polecenie backupu z terminala.
Alaa Ali,
1
Dziękuję za radę, ale zdecydowanie nie PermitRootLoginwłączyłem i nie planuję tego zmieniać. Najlepszą praktyką jest wyłączenie go i ssh tylko jako zwykły użytkownik (w razie potrzeby dodaj go do „sudoers”) i nigdy jako root.
Tom Brossman,