Pouvez-vous définir des mots de passe dans .ssh / config pour permettre la connexion automatique?

93

J'utilise Ubuntu 11.10. J'utilise sshquotidiennement pour me connecter à plusieurs serveurs, alors je mets leurs paramètres dans le .ssh/configfichier comme ceci:

Host Home
User netmoon
Port 22
HostName test.com

Existe-t-il un moyen de mettre des mots de passe pour chaque connexion dans ce fichier, de sorte que, lorsque le serveur demande le mot de passe, le terminal entre son mot de passe et l'envoie au serveur?

J'ai besoin de ça parce que parfois je m'éloigne du PC et quand je reviens en arrière, tapez un mot de passe et appuyez sur Enterle terminal CONNECTION CLOSED.

PS Je ne veux pas utiliser une paire de clés publique / privée.

Netmoon
la source
1
Je suis dans la même situation et je ne peux pas télécharger ma clé publique car je n’ai accès à ssh que pour svn. C’est-à-dire que si j’essaie ssh svnhost, j’obtiens "(succès (2 2 () (edit-pipeline svndiff1 entrées-absentes commit-revprops profondeur log-revprops partial-replay))))" "réponse svnserve et pas le shell
Uberto
Voir unix.stackexchange.com/a/83991/26493 et andre.frimberger.de/index.php/linux/… pour un moyen d'utiliser SSH_ASKPASS.
Olaf Dietsche

Réponses:

56

Échanger la sécurité pour plus de commodité ne se termine jamais bien ...

Pourriez-vous utiliser ssh-copy-idle openssh-clientpaquet?

De man ssh-copy-id:

ssh-copy-id est un script qui utilise ssh pour se connecter à une machine distante et ajouter le fichier d'identité indiqué au fichier ~ / .ssh / allowed_keys de cette machine.

Waltinator
la source
12
Cela ne fonctionne pas si l'administrateur distant insiste sur la désactivation de l'autorisation de clé publique ...
tomasz
2
Oui, mais être réaliste sur des systèmes sous votre entière supervision et contrôle directs ne constitue pas un compromis. Disons, par exemple, sur une machine virtuelle vagabonde sans connexion extérieure utilisée uniquement à des fins de développement sur un siège unique.
Scott
36
Insister pour une sécurité draconienne sans motif valable ne finit jamais non plus.
cwallenpoole
6
Parfois ça finit bien.
devth
3
IMHO, l'insistance de mots de passe pour l'authentification est plus risqué que non. J'ai souvent défini des mots de passe souvent utilisés pour ssh en tant que variables d'environnement, car je ne souhaite pas me souvenir d'un ensemble de chaînes arbitraires. En demandant aux utilisateurs de les entrer, on leur demande simplement d’être mal stockés.
œufs de pâques
26

Si vous ne voulez pas vraiment utiliser une paire de clés publique / privée, vous pouvez écrire un expectscript pour saisir automatiquement le mot de passe en fonction de l'adresse de destination.

Edit: Ce que je veux dire, c’est que vous pouvez avoir un script qui, d’une part, permet expectde saisir le mot de passe pour vous et, d’autre part, lit le mot de passe d’un utilisateur et d’un hôte donnés à partir d’un fichier de configuration. Par exemple, le script python suivant fonctionnera pour le scénario de journée ensoleillée:

#!/usr/bin/python                                                                                                                        
import argparse
from ConfigParser import ConfigParser
import pexpect

def main(args):
    url = args.url
    user, host = url.split('@', 1)

    cfg_file = 'ssh.cfg'
    cfg = ConfigParser()
    cfg.read(cfg_file)
    passwd = cfg.get(user, host)

    child = pexpect.spawn('ssh {0}'.format(url))
    child.expect('password:')
    child.sendline(passwd)
    child.interact()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Run ssh through pexpect')
    parser.add_argument('url')
    args = parser.parse_args()
    main(args)

et le format du fichier de configuration serait le suivant:

[user_1]
host1 = passwd_1
host2 = passwd_2

[user_2]
host1 = passwd_1
host2 = passwd_2

Remarque: comme expliqué, le script python aurait besoin d'être beaucoup plus complexe pour gérer toutes les erreurs possibles et les messages de questions de ssh et toutes les URL possibles (dans l'exemple, il est supposé que ce sera quelque chose comme user@host, mais la partie utilisateur isn ' t utilisé la plupart du temps), mais l’idée de base serait toujours la même. En ce qui concerne le fichier de configuration, vous pouvez utiliser un fichier de configuration différent ou utiliser .ssh/configet écrire votre propre code pour analyser ce fichier et obtenir le mot de passe d'un utilisateur et d'un hôte donnés.

jcollado
la source
pouvez-vous expliquer plus loin?
Netmoon
@ Netmoon, j'ai ajouté un petit exemple à ma réponse plus claire.
jcollado
Cela ne répond pas à la question de savoir comment mettre le mot de passe dans le fichier .ssh / config
Eric Woodruff
1
En effet, cela ne répond pas à cette question. Mais cela résout le problème: évitez de taper manuellement les mots de passe et de les stocker dans un fichier. Ce qui est joli ce que nécessite OP.
Arcesilas
19

Il existe également un sshpassprogramme pour cela. Comment utiliser: sshpass -p MyPa55word ssh [email protected]

igor
la source
29
À moins que vous ne préfixiez votre commande d'un espace ( sshpassau lieu de sshpass), vous venez de stocker votre mot de passe ("MyPa55word") dans le fichier historique de votre shell.
Waltinator
1
@waltinator bon point
igor
3
Eh bien, la question posée était correcte .ssh/config, pourquoi pas dans l’histoire de shell aussi?
Dark Egregious
Ce n'est pas officiellement sur Homebrew, mais vous pouvez installer à partir d'un dépôt tiers avec brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb. En savoir plus: gist.github.com/arunoda/7790979
Jacob Ford
read -s password; sshpass -p "$password" ssh [email protected]. Cela empêchera le mot de passe de figurer dans l'histoire
Alexander Bird
19

Que diriez-vous de ProxyCommand:

Host Home-raw
    HostName test.com
Host Home
   User netmoon
   Port 22
   ProxyCommand sshpass -pmypass ssh netmoon@%h-raw nc localhost %p

Vous pouvez utiliser à la ssh -Wplace de nc:

ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p
Eric Woodruff
la source
Cela ne fonctionnera pas comme prévu avec l' -Woption. Avez-vous une solution de contournement?
Toan Nguyen
2
Il me demande toujours le mot de passe avec cette commande proxy ...
Victor Piousbox
1
Je trouve aussi qu'il demande toujours un mot de passe. Tout ce que cela semble faire est de déplacer le problème de l’ test.comexigence d’un mot de passe à Homeun autre. À quoi ça sert? Quel est le truc pour le faire fonctionner?
Martin Bramwell
15

Non, ce n'est pas possible, j'ai bien peur.

La seule vraie alternative est d'utiliser des clés privées, mais vous avez dit que vous ne vouliez pas (pourquoi pas?).

Césium
la source
7
parce que je n'ai pas la permission de mettre une autre clé sur le serveur.
Netmoon
2
@Netmoon: Si vous pouvez vous connecter, vous pouvez ajouter une clé, non? Vous n'avez besoin que d'un accès en écriture à votre répertoire personnel, à moins que l'administrateur système ne configure étrangement les choses.
Scott Severance
4
@ScottSeverance Je pense que c'est la situation à laquelle cette question se réfère. Ne pas avoir la possibilité d'ajouter une clé. Oui c'est étrange, mais cela arrive souvent.
user239558
5
J'ai eu l'expérience très commune d'environnements d'hébergement partagé où l'accès par clé publique est désactivé. Même si vous pouvez ajouter des clés, elles ne sont pas utilisées. ça va à l'encontre de la raison oui, mais c'est la façon dont de nombreux hébergeurs installent leurs serveurs
Billynoah
1
Il y a des réponses qui montrent que c'est possible
Eric Woodruff
8

Vous pouvez créer un simple remplacement de script ssh dans / usr / local / bin:

#!/bin/bash

host=$1
password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config`

if [[ -z "$password" ]]; then
  /usr/bin/ssh $*
else
  sshpass -p $password /usr/bin/ssh $*
fi

Et puis dans votre fichier ~ / .ssh / config, vous pouvez utiliser

Host foohost
    User baruser
    #Password foobarpassword
Arek Burdach
la source
4

J'utilise une application de VanDyke Software appelée SecureCRT .

http://www.vandyke.com/products/securecrt/

Ce n'est pas gratuit, mais à un prix très raisonnable. Je l'utilise depuis des années (fonctionnant sous Windows ou utilisant Wine) pour l'accès à distance, l'émulation de terminal et la gestion de réseaux (dispersés). Ils ont finalement publié une version Linux native au début de 2011.

Il prend en charge les paramètres de connexion complexes (ou scripts), les mots de passe stockés (ou certificats), les sessions multiples avec onglets, etc.

Au démarrage, vous pouvez choisir la cible distante (et le protocole) dans une liste structurée (vue arborescente) de machines distantes (ou locales) stockées, ou simplement créer une connexion (qui est ensuite stockée).

Je l'ai trouvé particulièrement utile pour les sites distants dotés d'une authentification avancée, de ports non standard ou de la négociation d'accès par pare-feu.

Si vous effectuez beaucoup d'accès à distance (dans le cadre de votre rôle principal), cette application justifiera ses dépenses au cours du premier mois d'utilisation.

david6
la source
désolé, je ne comprends pas. peux-tu expliquer ?
Netmoon
1
reformulé pour vous ..
david6
2
Depuis la publication de la réponse ci-dessus, plusieurs versions de SecureCRT ont été lancées, dont la dernière que VanDyke vient de publier début décembre 2013. Chaque itération a amélioré le programme, le rendant encore plus polyvalent. Il possède également une API riche qui permet au programme d'être contrôlé / interfacé avec les scripts Python / VB. SecureCRT fait partie de ma boîte à outils principale depuis une bonne décennie et je le recommande vivement.
Ville
D'accord. Je continue de bêta-tester chaque nouvelle version et j'ai été fortement impliqué dans les premiers tests de portage sur Ubuntu .
david6
2

En répondant à la question que vous avez posée, non, il n'est pas possible de configurer un mot de passe par défaut dans un fichier de configuration ssh.

Mais si en effet, comme vous le dites, c’est "parce que je me tiens parfois à l’écart du PC et que quand je reviens en arrière, tapez un mot de passe et appuyez sur Enterle terminal pour dire CONNECTION CLOSED" , pourquoi ne pas empêcher la fermeture de la session à la place? SSH peut maintenir les connexions en vie pour vous.

Host Home
  User netmoon
  Port 22
  HostName test.com
  ServerAliveInterval 300
  ServerAliveCountMax 2
Krzysztof Jabłoński
la source
1

Merci, Arek pour l'inspiration ...

Plutôt que d'exécuter un autre processus shell, il ne s'agit que d'une fonction s'exécutant dans le shell bash actuel. Il exécute une seule awkcommande pour analyser le fichier de configuration et déterminer s'il doit extraire le mot de passe d'une variable shell ou du mot de passe en texte clair écrit dans le fichier de configuration ssh (avec awkau evallieu de à describecause de problèmes rencontrés en utilisant describe).

J'ai essayé de nombreuses manières d'utiliser sshpassdirectement dans un sshfichier de configuration en utilisant ProxyCommand, mais rien ne semblait fonctionner comme prévu, sauf lorsque je pouvais me connecter à une boîte via RSA. Mais ensuite, je devais envoyer un mot de passe pour ouvrir mon répertoire crypté. Cependant, ma fonction ci-dessous semble fonctionner pour moi dans tous les cas, même pour Cygwin.

# In your .bash_profile
function ssh(){
    host=$1;
    unset PASSWORD
    unset PASSVAR
    eval $(awk "/ *#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1 } / *#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^#?[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1 } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config)
    if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then
        /usr/bin/ssh -q $* 2>/dev/null
    else
       if [[ -n "$PASSVAR" ]]; then
          PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-})
       fi
       /usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/ssh -q $* 2>/dev/null
    fi
}
# and setup your passwords (perhaps in .bashrc instead...)
MYPASS_ENVVAR=SomePassword
MYPASSWD_FROM_FILE=$(</home/me/.passwd_in_file)

Ensuite, une ~/.ssh/configsection ressemble à ceci:

Host MyHostname
 Port 22
 Hostname 2.1.2.2
 User merrydan
 #Passvar MYPASS_ENVVAR
 #Password Some!Password

Si un #Passvar existe dans la section config, cela remplace le #Password.
$MYPASS_ENVVARest la variable d'environnement contenant votre mot de passe.

Prendre plaisir!

Joyeux dan
la source
1

La réponse de @BrunoPereira à cette question montre une méthode alternative pour se connecter sans entrer explicitement un mot de passe et en évitant les clés ssh.

Vous pouvez créer un script, un alias ou une fonction dans votre ~/.bashrcpour exécuter rapidement cette commande.

De toute évidence, il convient de prendre en compte des considérations de sécurité avec cette approche.

enzotib
la source
Il est bon que vous vous connectiez à une solution. Toutefois, il est également judicieux de publier la solution ici. De cette façon, si le lien est supprimé (comme cela arrive parfois sur l'échange de pile), il reste une réponse utilisable ici.
Paul
0

Voici ma variante élaborée de la réponse de @ ArekBurdach. Il offre les extensions suivantes:

  • l' hôte peut être n'importe où dans la sshligne de commande; c'est à dire qu'il supporte également la ssh <args> <host> <commands>syntaxe
  • ne code pas le chemin d'accès à ssh
  • analyse plus robuste de ssh_config
  • Bonus: emballage pour scpaussi

ssh-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SSH arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        sshArgs[ARGV[i]] = 1
    }

    # Only process the first argument; all others are the command-line arguments
    # given to ssh.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in sshArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which ssh)" "$@"
else
    "$(which ssh)" "$@"
fi

scp-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SCP arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        colonIdx = index(ARGV[i], ":")
        if (colonIdx > 0) {
            scpArgs[substr(ARGV[i], 1, colonIdx - 1)] = 1
        }
    }

    # Only process the first argument; all others are the command-line arguments
    # given to scp.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in scpArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which scp)" "$@"
else
    "$(which scp)" "$@"
fi

Installation

Définissez les alias dans votre ~/.bashrc:

alias ssh=ssh-wrapper
alias scp=scp-wrapper

Configuration

Avec la IgnoreUnknowndirective, sshne se plaint pas d'une Passworddirective nouvellement introduite , donc (contrairement à la réponse de @ ArekBurdach), nous pouvons faire en sorte que cela apparaisse comme une "vraie" configuration. Si vous n'aimez pas cela, il est facile de remplacer le script par celui qui a été commenté.

# Allow specifying passwords for Host entries, to be parsed by ssh-wrapper.
IgnoreUnknown Password

Host foohost
    User baruser
    Password foobarpassword
Ingo Karkat
la source
0

Si vous n'avez pas d'accès direct à la paire de clés, vous pouvez chiffrer le mot de passe sur votre ordinateur local.

Pour ce faire, chiffrez votre mot de passe en utilisant la clé en plus de la commande ProxyCommand de @Eric Woodruff.

Une façon de combiner est d'utiliser un tuyau:

openssl rsautl -decrypt -inkey /path/to/decrypt_key -in /path/to/encrypted_password  | sshpass ssh real-destination -tt

Host real-destination
    Hostname test.com
    User netmoon
Willian Z
la source
0

Il existe une légère variante d'une manière décrite dans le blog sur la façon d'utiliser sshpass qui peut être trouvée ici . Étant donné que vous avez un mot de passe crypté gpg (comment cela est décrit dans le blog), vous pouvez faire quelque chose comme ceci:

 sshpass -p $(echo $(gpg -d -q .sshpasswd.gpg)) ssh your_desination.xyz

et enregistrez simplement cette commande sous un alias dans votre .bashrc.

Si vous souhaitez créer un tunnel via cette connexion, vous pouvez faire quelque chose comme:

 Host actual_dest
      Hostname actual.dest.xyz
      User username
      ProxyCommand sshpass -p $(echo $(gpg -d -q ~/.sshpasswd.gpg)) \ 
                   ssh your_destination.xyz nc %h %p
ricffb
la source