この rsync + ssh cron ジョブで「Permission denied (publickey)」エラーが発生するのはなぜですか?

この rsync + ssh cron ジョブで「Permission denied (publickey)」エラーが発生するのはなぜですか?

ローカル ドライブに頻繁にバックアップを作成し、それをリモート サーバーに毎日同期したいと考えています。

ターゲットサーバーはSSHキー(パスワードなし)アクセスのみに設定されています。そのサーバーのプライマリSSHキーはパスフレーズで保護されているため、無人バックアップに使用する2番目のSSHキー(パスフレーズで保護されていない)+ユーザーを作成しました- この方法では、cron の実行時にパスフレーズを入力するために立ち会う必要はありません。

cron と rsync を使用していますが、すべてのコマンドは個別には機能しますが、組み合わせると失敗します。

トラブルシューティング中に私が最も遠くまで行ったのは

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

エラーを返す

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]

これをさらにトラブルシューティングする方法に関するヒントはありますか?


これまでに試したことは次のとおりですが、アイデアが尽きています。

  1. Cronは確実に実行されていますps aux | grep cron
  2. /var/log/syslog には異常なしSep 7 13:22:01 desktop CRON[6735]: (tom) CMD (sh /home/tom/Documents/Scripts/offsite-backup)

  3. バックアップユーザーが作業しているときにターミナルでリモートサーバーにSSH接続するssh [email protected]

  4. ターミナルでコマンドを実行すると完璧に動作しますrsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
  5. バックアップユーザーキーへのパスを手動で指定しても効果はありませんrsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/

  6. 機能しないコマンドを簡単なテストコマンドに置き換えると、echo "Hello world" > ~/Desktop/test.txt

  7. コンピュータに向かって叫んだり罵ったりしても効果はありませんでした(ただし、一時的には気分が良くなりました)。


編集1:

ここに私の crontab ファイルとそれが呼び出すスクリプトがあります。

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

そして

#!/bin/bash

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

編集2:

明確にするために、/var/log/auth.logターゲットサーバーには次の行が含まれています。Sep 11 08:23:01 <hostname> CRON[24421]: pam_unix(cron:session): session closed for user rootこれは、ローカルで毎分cronを実行していないのに、サーバーログに毎分新しいエントリが表示されるため、混乱を招きます。全てサーバー上のユーザー (root を含む) は空であり、何も実行しません。

また、ユーザー「backups-only」はサーバー上にのみ作成され、権限が制限され、専用の SSH キーがデスクトップ マシンにコピーされました。コマンドを手動で実行するとすべてが機能するため、これが正しい方法であると想定しています。

上に投稿した crontab ファイルは、デスクトップ マシンのユーザー「tom」のものです。私の意図は、ユーザー「backups-only」としてサーバーにログインするスクリプトを呼び出すことです。バックアップ スクリプト (その中のコマンドではなく) を実行してみましたが、正常に接続され、機能しました。デスクトップでユーザー「tom」として実行しました。これは、機能しない cron ジョブを作成したユーザーと同じです。これが、その成功したログインに対応するサーバー ログからの出力です。

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

答え1

コマンドラインからはすべて正常に動作しているので、このエラーはPermission denied (publickey)、SSH 部分がrsync指定されたユーザー名とは異なる ID ファイルを使用していることを意味します。

からヤンのコメントrsync元の質問では、を使用してコマンドで ID ファイルを指定できます-e 'ssh -i /path/to/identity.file' ...

以下のコマンドを使用して cron で新しい環境を開始し、ファイルへの完全なパスを指定すると、問題は解決するようです。

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/"

この発見にはまだとても興味があります。これはおそらく cron、最小限の環境変数で起動するという事実、および ssh-agent に関係しているのでしょう。数日以内に同じシナリオを設定してテストし、報告する予定です。

答え2

私を忙しくさせていたこの問題を解決しました。

SSH の ID を規定しているにもかかわらず、SSH 経由で RSYNC に接続できません...何も行われません... rsync は「権限が拒否されました」と表示し、ssh は「read_passphrase: /dev/tty を開けません: このタイプのデバイスまたはアドレスがありません」と表示します

しかし、crontabにはルートとは異なる独自の環境があることを説明する投稿を読みました。私はすでにそれを知っていましたが、SSH-AGENTを使用するときにSSHにどのような影響を与えるかを理解していませんでした。

しかし、私の SSH キー交換は PassPhrase を使用して行われます。そのため、環境が異なり、SSH 経由の RSYNC が入力できないパスフレーズを期待している場合、SSH デバッグ情報にもエラーが表示されます。

「debug1: read_passphrase: /dev/tty を開けません: そのようなデバイスまたはアドレスはありません」 => はい、TTY がありません = パスフレーズがありません = 許可されていません

私のマシンでは、SSHエージェントを起動するために「キーチェーン」を使用しています。これにより、リモート接続を試みるたびにパスフレーズを再入力する必要がなくなります。キーチェーンは、次の情報を含むファイルを生成します。

SSH_AUTH_SOCK = /tmp/ssh-PWg3yHAARGmP/agent.18891; エクスポート SSH_AUTH_SOCK; SSH_AGENT_PID = 18893; エクスポート SSH_AGENT_PID;

==> SSH-AGENT コマンドは同じ情報を返します。

したがって、最終的には、現在のセッションに関連するこれらの情報によって、以前にすでに実行され記憶されているためパスフレーズを入力する必要がなく、現在のセッションの将来の認証が可能になります...

==> 解決策はそこにあります...crontab によって起動されたスクリプト内で、この情報を含むファイルを「ソース」するか、crontab のコマンド ラインで実行するだけで十分です...

例: 14 09 * * *. /home/foo/.keychain/foo.serveur.org-sh && scp -vvv -P 22 /tmp/mon_fic/toto.sh[メールアドレス]:. >> /var/log/check_connexion.log 2> & 1 または、SSH を使用して接続を開始するスクリプトでコマンド「source /home/foo/keychain/foo.server.org-sh」を使用します。

=> このソースがあれば、もう心配する必要はありません。SSH_AUTH_SOCK と SSH_AGENT_PID の情報は Crontab の環境にロードされるため既知であり、SSH 経由の RSYNC は問題なく動作します。

忙しかったけど、今はうまくいっています :)

答え3

SSH エージェント転送を使用する場合の注意:

-e "ssh -i /path/to/key"リモート ホスト上のスクリプトをデバッグしているときにこの動作が見られるのは、フラグがあっても、ssh がサーバー上のキーではなくローカル (転送された) キーを使用するためです。

具体的な例: 開発サーバーに、ssh 経由で rsync を使用して「データ サーバー」からデータを取得するスクリプトがあります。開発サーバーにログインして実行すると、すべて正常に動作しますが、cron から実行すると、権限が拒否されます。SSH プロセスに詳細度を追加すると (フラグ-vv)、次のことに気付きました。

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).

ここで私が気づいたのは、まったくの偶然ですが、ローカル ホスト ("nighty") と開発サーバー ("juanr") のユーザー名が異なっていたことです。

開発サーバー上のキーが「明示的」としてマークされているにもかかわらず、ラップトップから転送されたキーを使用してログインしていることに注目してください。ssh-copy-idこの時点で を実行しても何も解決されません。これは、開発サーバーからのキーではなく、転送されたキーを再インストールするだけだからです。エージェント転送で ssh-copy-id を使用する場合は、-i フラグを使用してインストールするキーを指定する必要がありますssh-copy-id -i ~/.ssh/id_rsa.pub user@host

答え4

ホスト ファイルをクリーンアップするという古いトリックをすでに試しましたか? つまり、次のようになります:

rm ~/.ssh/known_hosts

ssh によって再構築され、古いデータが削除されるため、試してみる価値はあります。もちろん、特定の IP / ホストに属する部分を削除することもできます。

その他の質問: cron ジョブは UID で実行されていますか、それともユーザー cron または root として実行されていますか?

関連情報