Forcer SSH à utiliser un shell spécifique

29

Existe-t-il un moyen de forcer SSH à utiliser un shell particulier sur l'extrémité distante, quel que soit le shell par défaut de l'utilisateur?

J'ai essayé des solutions similaires à:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

mais malheureusement, le shell par défaut sur l'extrémité distante est responsable de l'analyse de la partie "commande complexe à plusieurs lignes", et j'ai du mal à l'échapper suffisamment pour fonctionner à la fois pour les utilisateurs du shell Bash et C.

plinehan
la source

Réponses:

8

Je ne pense pas que cela soit possible, du moins avec les systèmes basés sur openssh. Si vous en avez la possibilité, une meilleure solution pourrait être de créer un fichier de script shell, puis de l'exécuter avec la méthode que vous avez publiée. Cela aurait l'avantage de minimiser la quantité d'échappement nécessaire, mais laisserait un fichier qui devrait être supprimé (peut-être comme la dernière étape du script).

sysadmin1138
la source
1
C'est ce que j'ai finalement fait, mais en utilisant scp. Une bonne idée.
plinehan
16

Utilisez un hérédoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Ignacio Vazquez-Abrams
la source
ne devriez-vous pas utiliser "-s" pour bash pour lire les commandes de stdin?
Weboide
Ce n'est pas toujours nécessaire.
Ignacio Vazquez-Abrams
Je voterais contre si je le pouvais car cela empêche les commandes d'avoir accès à stdin et la question était d'invoquer un shell particulier.
Eric Woodruff
3
@EricWoodruff, ... invoquer un shell particulier (dans ce cas bash) est exactement ce que cela montre comment faire.
Charles Duffy
1
Pour info vous pouvez aussi faire cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Ainsi, au lieu d'une étape, vous avez deux étapes: étape 1 copiez votre script dans un fichier, étape 2 catle script vers ssh.
Trevor Boyd Smith
10

Utilisez des connexions basées sur des clés, et non pas basées sur un mot de passe. Ensuite, vous pouvez ajouter une (liste de) "commande (s) forcée (s)" à votre clé publique ssh (dans le champ "options" en cas de SSH1) qui est installée sur le serveur (dans le fichier ~ / .ssh / authorized_keys pour SSH1 , ~ / .ssh2 / autorisation pour SSH2).

Faites votre commande forcée pour que votre shell souhaité soit appelé ...

Plus: Vous pouvez associer au plus une commande forcée à une clé donnée. Si vous avez besoin de plusieurs commandes forcées à des fins différentes, vous devez configurer différentes clés. (Bien sûr, vous pouvez mettre plusieurs choses dans un script, que vous appelez via une commande forcée. Mais sachez que les commandes forcées sont toujours exécutées pour un compte / clé donné si l'utilisateur se connecte, qu'il ait demandé quelque chose de différent à exécuter. Si vous voulez toujours honorer la commande d'origine demandée, regardez comment exploiter la $SSH_ORIGINAL_COMMANDvariable ...)

Renseignez-vous sur les "commandes forcées" via Google .

Kurt Pfeifle
la source
Bon produit. Ce graphique sur la page O'Reilly est très joli. Dans mon cas particulier, cependant, je veux pouvoir forcer cela pour tous les utilisateurs, pas seulement les utilisateurs qui ont correctement configuré leurs clés. Je n'ai pas non plus de racine sur les machines serveur, donc je ne peux pas éditer de fichiers comme /etc/sshrc.
plinehan
Eh bien, c'est toujours le serveur (ou mieux: celui qui exerce le contrôle sur le serveur) qui appelle les coups de feu lorsque vous vous connectez à son service .... Le «propriétaire» du serveur décide de ce qui peut être fait avec. - Vous ne pouvez rien forcer «pour un ou plusieurs utilisateurs» si vous ne disposez pas de privilèges plus élevés qu'eux.
Kurt Pfeifle
Si le client peut exécuter des commandes arbitraires, il peut également exécuter un shell arbitraire en tant que commande.
Eric Woodruff
@KurtPfeifle ce lien vers O'Reilly est rompu
Brian Vandenberg
@BrianVandenberg: Thx pour l'astuce. J'ai supprimé ce lien maintenant.
Kurt Pfeifle
2

Vous pouvez utiliser l' -toption pour forcer l'allocation d'un pseudo-tty pour le programme que vous souhaitez démarrer, comme si vous exécutiez le shell standard. Passez ensuite le shell que vous voulez comme un argument ancien simple.

Avec cette technique, vous pouvez non seulement utiliser n'importe quel shell installé, mais vous pouvez également ouvrir vim et d'autres programmes qui nécessitent un ATS, à partir d'une seule commande. Ce qui est cool si vous écrivez un script shell qui vous connecte quelque part et ouvre un fichier sur vim, ou htop ou quelque chose.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

Je ne sais pas s'il s'agit d'un shell de connexion, mais il existe des options pour que bash agisse comme un shell de connexion, donc votre shell pourrait l'avoir aussi.

Fábio Santos
la source
1

Étonnamment, je vois des résultats différents avec les éléments suivants:

exécuter en tiret:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

vs bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

L'affichage de la commande entièrement citée fonctionne comme prévu.

Eric Woodruff
la source
1
Pas étonnant du tout. Le démon ssh distant s'exécute efficacement sh -c "$*". Ainsi, vous courez sh -c "/bin/bash -c echo <(cat)"; la echocommande elle-même est le seul argument transmis à -c, et <(cat)est un argument distinct tout à fait.
Charles Duffy
0

J'ai fait face à une situation similaire il y a quelque temps où j'avais besoin d'utiliser le coprocessus ksh pour sqlplus et je n'avais qu'un ssh à travers lequel les lectures et les écritures devaient avoir lieu.

Une façon de procéder consiste à diriger toutes vos commandes dépendantes sur une seule ligne (utilisez;) vers / usr / bin / ksh sur la machine distante. par exemple:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
aws
la source