ssh Autorisation refusée uniquement dans le travail cron

13

Ayant un problème très étrange. J'ai créé un petit script bash qui exécute une commande sur un hôte distant via ssh (en utilisant l'authentification par clé publique).

Lorsque j'exécute ce script manuellement à partir de la ligne de commande, cela fonctionne bien, mais lorsqu'il est placé dans /etc/cron.hourly, il échoue avec une Permission denied, please try again.erreur.

  • J'ai explicitement défini la clé dans le script en utilisant ssh -i /root/.ssh/id_rsa user@remote "command";
  • le script s'exécute en tant que root (j'ai ajouté un echo `id` > /tmp/whoami.logà revérifier); et
  • la clé ssh n'est pas protégée par mot de passe ...

Le système est un serveur Ubuntu 12.04, je n'ai pas beaucoup d'accès du côté distant pour dépanner, mais comme je l'ai dit, exécuter ssh manuellement ou le même script bash à partir de la ligne de commande fonctionne.

Une idée pourquoi cela se produit ou comment y remédier ??

mettre à jour

il s'est avéré que je me trompais, et la clé ssh était protégée par mot de passe (avec le trousseau chargeant l'agent ssh), d'où la raison pour laquelle elle a échoué à partir d'un script mais pas lors de l'exécution à partir de la session bash. L'ajout . ~/.keychain/$HOSTNAME-shà mon script a résolu le problème (merci à @grawity qui m'a pointé dans la bonne direction et a fourni une réponse complète).

Yoav Aner
la source
Êtes-vous sûr de l'exécuter manuellement en utilisant cette clé particulière? Testez à nouveau après la suppression des variables d'environnement SSH_AUTH_SOCKet de suppression KRB5CCNAME.
user1686
Merci pour la suggestion. Je ne suis pas sûr de bien vous comprendre cependant. Je suis presque sûr qu'il utilise cette clé particulière, car je suis capable de me connecter / d'exécuter une commande sur l'hôte distant lors de l'exécution manuelle. Que dois-je exactement tester à nouveau après la suppression de ces variables?
Yoav Aner
Aussi - je n'utilise pas ssh-agent, donc SSH_AUTH_SOCKje ne sais pas comment est lié (même si je suis heureux d'essayer quoi que ce soit). J'accède directement au fichier de clés et le fichier de clés n'est pas protégé par mot de passe. Quant à KRB5CCNAMEune recherche rapide, cela a quelque chose à voir avec Kerberos. Encore une fois - ne voyez pas le lien avec ce problème, mais peut-être que je manque quelque chose ici ...
Yoav Aner
Testez votre script, bien sûr. Vous ne pouvez pas être «à peu près sûr qu'il utilise cette clé particulière» tant que vous ne le faites pas, car les tâches cron s'exécutent dans un environnement différent des commandes interactives. Ce serait encore mieux si vous -vssh
ajoutiez
Mais je le fais. J'utilise explicitement la clé en utilisant la ssh -icommande dans les deux cas ... J'essaierai de supprimer ces variables dans le script et de voir. Bonne suggestion à ajouter -v- je vais aussi l'ajouter.
Yoav Aner

Réponses:

11

Les commandes interactives et les tâches cron s'exécutent dans différents environnements. En particulier, une session interactive peut avoir un agent SSH en cours d'exécution ou un Kerberos TGT stocké. En raison de la façon dont sshles méthodes d'authentification sont commandées, vous ne pouvez pas être sûr que votre clé est utilisée simplement parce que vous avez ajouté l' -ioption.

  • Si un agent SSH est en cours d'exécution, le sshclient essaie toujours les clés d'agent avant d' utiliser les clés spécifiées explicitement.

  • Si le réseau utilise Kerberos et qu'un TGT Kerberos est présent, OpenSSH l'utilisera avant d' essayer l'authentification par clé publique.

Je ne sais rien de votre environnement, mais ces deux possibilités sont faciles à vérifier:

  1. Ajoutez unset SSH_AUTH_SOCKet unset KRB5CCNAMEavant la sshcommande, puis exécutez manuellement le script modifié.

    Cela empêchera le script de voir l'agent ou les tickets Kerberos et n'utilisera que la clé explicitement spécifiée.

  2. Ajoutez l' -voption à ssh. Cela affichera plus de détails sur la façon dont l'authentification se produit.

Vous pouvez également ajouter -oIdentitiesOnly=yesà la sshcommande; cela l' obligera à utiliser la clé spécifiée .


Et si vous ajoutez des conseils pour accéder à l'agent depuis cron - encore mieux

Ceci n'est généralement pas recommandé, car l'agent est généralement étroitement lié à votre session de connexion interactive. En particulier, il ne démarre que lorsque vous vous connectez et est tué lorsque vous vous déconnectez - et il a besoin de votre mot de passe pour déverrouiller les clés SSH (en supposant qu'elles soient protégées par mot de passe).

Vous avez mentionné "Keychain" - est-ce le programme OS X ou le script Linux? (Je ne connais pas grand-chose à l'architecture de Mac OS X, mais AFAIK, il est beaucoup plus difficile d'accéder à l'agent ssh de l'utilisateur à partir d'un cronjob ...)

user1686
la source
1
Vous pouvez utiliser ssh-cron pour configurer des connexions SSH planifiées pour sécuriser les serveurs sans exposer vos clés SSH, mais en utilisant l'agent SSH. superuser.com/questions/463540/…
Luchostein
5

Une autre solution à ce problème consiste à définir cron sur ssh dans la zone locale pour exécuter à son tour la commande ssh au lieu d'exécuter le fichier ou la commande par son chemin absolu local. Cela met en cache le KRB5CCNAME et fonctionne là où / path / command ne fonctionne pas.

# Fails:
0 * * * * /home/user/sshscript.sh

# Works:
0 * * * * /usr/bin/ssh user@localhost /home/user/sshscript.sh

#!/bin/bash
# Works:
unset SSH_AUTH_SOCK
unset KRB5CCNAME
/usr/bin/ssh user@localhost /home/user/sshscript.sh
mmond
la source
1

Vous pouvez utiliser ssh-cron pour configurer des connexions SSH planifiées pour sécuriser les serveurs sans exposer vos clés SSH, mais en utilisant l'agent SSH.

Luchostein
la source
Les dépendances ne sont pas disponibles sur Homebrew, donc l'installation semble être compliquée. Clé sans mot de passe, je suppose…: - /
Charlie Gorichanaz
-1

vous pouvez exécuter votre script ou commande dans crontab comme:

0 * * * * bash -c -l "/home/user/sshscript.sh"

ou

0 * * * * bash -c -l "ssh root @ yourhost 'echo $ HOSTNAME'"

pawan
la source
1
OP essaie déjà d'exécuter le script via cron; donc cela ne semble pas vraiment apporter de réponse.
bertieb