Können Sie Kennwörter in .ssh / config festlegen, um die automatische Anmeldung zu ermöglichen?

93

Ich benutze Ubuntu 11.10. Ich verwende sshfür die Verbindung mit vielen Servern täglich, damit ich ihre Parameter in die .ssh/configDatei wie folgt setzen:

Host Home
User netmoon
Port 22
HostName test.com

Gibt es eine Möglichkeit, Kennwörter für jede Verbindung in diese Datei einzufügen, sodass das Terminal, wenn der Server nach dem Kennwort fragt, sein Kennwort eingibt und es an den Server sendet?

Ich brauche das, weil ich manchmal vom PC wegstehe und wenn ich zurückgehe, ein Passwort eingebe und auf Enterdas Terminal drücke, sagt CONNECTION CLOSED.

PS Ich möchte kein öffentliches / privates Schlüsselpaar verwenden.

Netmoon
quelle
1
Ich bin in der gleichen Situation und kann meinen öffentlichen Schlüssel nicht hochladen, da ich nur für svn ssh-Zugriff habe. Das ist, wenn ich ssh svnhost versuche, erhalte ich "(Erfolg (2 2 () (edit-pipeline svndiff1 abwesende-Einträge commit-revprops Tiefe log-revprops teilweise-replay))" und nicht die Shell
Uberto
Informationen zur Verwendung finden Sie unter unix.stackexchange.com/a/83991/26493 und andre.frimberger.de/index.php/linux/…SSH_ASKPASS .
Olaf Dietsche

Antworten:

56

Sicherheit aus Bequemlichkeitsgründen auszutauschen, hört nie gut auf ...

Könnten Sie ssh-copy-idaus dem openssh-clientPaket verwenden?

Von man ssh-copy-id:

ssh-copy-id ist ein Skript, das ssh verwendet, um sich bei einem Remote-Computer anzumelden und die angegebene Identitätsdatei an die Datei ~ / .ssh / authorized_keys dieses Computers anzuhängen.

Waltinator
quelle
12
Dies funktioniert nicht, wenn der Remote-Administrator darauf besteht, die Autorisierung öffentlicher Schlüssel zu deaktivieren ...
tomasz
2
Ja, aber auf Systemen unter Ihrer direkten Aufsicht und Kontrolle realistisch zu sein, ist kein Kompromiss. Nehmen wir zum Beispiel an, Sie arbeiten auf einer virtuellen Maschine ohne externe Verbindungen, die ausschließlich zu Entwicklungszwecken auf einem einzelnen Arbeitsplatz verwendet werden.
Scott
36
Das Bestehen auf drakonischer Sicherheit ohne Grund endet auch nie gut.
Cwallenpoole
6
Manchmal endet es gut.
Devth
3
IMHO ist das Bestehen auf Passwörtern für die Authentifizierung mehr Risiko als nicht. Ich habe häufig Passwörter für ssh als Umgebungsvariablen festgelegt, da ich mich nicht an eine Reihe beliebiger Zeichenfolgen erinnern möchte. Durch die Forderung der Benutzer, sie einzugeben, werden sie lediglich aufgefordert, schlecht gespeichert zu werden.
Eggmatters
26

Wenn Sie ein öffentliches / privates Schlüsselpaar nicht wirklich verwenden möchten, können Sie ein expectSkript schreiben , um das Kennwort abhängig von der Zieladresse automatisch für Sie einzugeben.

Bearbeiten: Was ich meine ist, dass Sie ein Skript haben können, das expectzum einen das Passwort für Sie eingibt und zum anderen das Passwort für einen bestimmten Benutzer und Host aus einer Konfigurationsdatei liest. Das folgende Python-Skript funktioniert beispielsweise für das Sonnentages-Szenario:

#!/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)

und das Konfigurationsdateiformat wäre wie folgt:

[user_1]
host1 = passwd_1
host2 = passwd_2

[user_2]
host1 = passwd_1
host2 = passwd_2

Hinweis: Wie bereits erläutert, müsste das Python-Skript wesentlich komplexer sein, um alle möglichen Fehler- und Fragenachrichten von ssh und alle möglichen URLs zu verarbeiten (im Beispiel wird davon ausgegangen, dass dies in etwa der Fall ist user@host, aber der Benutzerteil ist nicht ' Die meiste Zeit nicht verwendet), aber die Grundidee wäre immer noch die gleiche. In Bezug auf die Konfigurationsdatei können Sie eine andere Konfigurationsdatei verwenden oder .ssh/configIhren eigenen Code verwenden und schreiben, um diese Datei zu analysieren und das Kennwort für einen bestimmten Benutzer und Host abzurufen.

jcollado
quelle
kannst du weiter erklären
Netmoon
@Netmoon Ich habe meiner Antwort ein kleines Beispiel hinzugefügt, um es klarer zu machen.
jcollado
Dies beantwortet nicht die Frage, wie das Passwort in der .ssh / config-Datei abgelegt werden soll
Eric Woodruff
1
Tatsächlich beantwortet es diese Frage nicht. Aber es löst das Problem: Vermeiden Sie es, Kennwörter manuell einzugeben und in einer Datei zu speichern. Welches ist hübsch, was OP erfordert.
Arcesilas
19

Dafür gibt es auch ein sshpassProgramm. Wie benutzt man: sshpass -p MyPa55word ssh [email protected]

igor
quelle
29
Sofern Sie Ihrem Befehl kein Leerzeichen ( sshpassanstelle von sshpass) voranstellen, haben Sie gerade Ihr Kennwort ("MyPa55word") in der Verlaufsdatei Ihrer Shell gespeichert.
Waltinator
1
@ Waltinator guter Punkt
igor
3
Nun, der Fragesteller war damit einverstanden .ssh/config, warum nicht auch in der Shell-Geschichte?
Darth Egregious
Es ist nicht offiziell auf Homebrew, aber Sie können von einem Drittanbieter-Repo mit installieren brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb. Mehr: gist.github.com/arunoda/7790979
Jacob Ford
read -s password; sshpass -p "$password" ssh [email protected]. Dadurch wird verhindert, dass das Kennwort im Verlauf angezeigt wird
Alexander Bird
19

Wie wäre es mit ProxyCommand:

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

Sie können ssh -Wanstelle von ncauch verwenden:

ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p
Eric Woodruff
quelle
Mit der -WOption funktioniert es nicht wie erwartet . Haben Sie eine Problemumgehung?
Toan Nguyen
2
Es fragt mich immer noch nach dem Passwort für diesen Proxy-Befehl ...
Victor Piousbox
1
Ich finde es auch immer noch fragt nach einem Passwort. Alles, was dies zu tun scheint, ist, das Problem von der test.comAnforderung eines Passworts zur HomeAnforderung eines Passworts zu verschieben. Was ist der Punkt? Was ist der Trick, um es zum Laufen zu bringen?
Martin Bramwell
15

Nein, das ist leider nicht möglich.

Die einzige echte Alternative besteht darin, private Schlüssel zu verwenden, aber Sie haben gesagt, Sie möchten nicht (warum nicht?).

Cäsium
quelle
7
weil ich keine Erlaubnis habe, einen anderen Schlüssel auf den Server zu legen.
Netmoon
2
@Netmoon: Wenn Sie sich anmelden können, können Sie einen Schlüssel hinzufügen, richtig? Sie benötigen nur Schreibzugriff auf Ihr Home-Verzeichnis, es sei denn, der Sysadmin hat die Dinge seltsam eingerichtet.
Scott Severance
4
@ ScottSeverance Ich denke, das ist die Situation, auf die sich diese Frage bezieht. Sie können keinen Schlüssel hinzufügen. Ja, es ist seltsam, aber es kommt oft vor.
user239558
5
Ich habe die sehr häufige Erfahrung mit Shared Hosting-Umgebungen gemacht, in denen der Zugriff auf öffentliche Schlüssel deaktiviert ist. Obwohl Sie also Schlüssel hinzufügen können, werden diese nicht verwendet. Das ist gegen den Verstand, ja, aber so richten viele Hosting-Anbieter ihre Server ein
billynoah
1
Es gibt Antworten, die zeigen, dass es möglich ist
Eric Woodruff
8

Sie können einen einfachen ssh-Skriptersatz in / usr / local / bin erstellen:

#!/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

Und dann können Sie in Ihrer ~ / .ssh / config-Datei verwenden

Host foohost
    User baruser
    #Password foobarpassword
Arek Burdach
quelle
4

Ich verwende eine Anwendung von VanDyke Software namens SecureCRT .

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

Es ist nicht kostenlos, aber sehr günstig. Ich benutze es seit Jahren (unter Windows oder mit Wine) für den Remotezugriff, die Terminalemulation und die (verteilte) Netzwerkverwaltung. Sie veröffentlichten schließlich Anfang 2011 eine native Linux-Version davon.

Es werden komplexe Anmeldeeinstellungen (oder Skripte), gespeicherte Kennwörter (oder Zertifikate), mehrere Sitzungen mit Registerkarten usw. unterstützt.

Beim Start können Sie aus einer strukturierten Liste (Baumansicht) gespeicherter entfernter (oder lokaler) Maschinen auswählen, welches entfernte Ziel (und welches Protokoll) Sie verwenden möchten, oder einfach eine Verbindung erstellen (die dann gespeichert wird).

Ich fand es besonders nützlich für entfernte Standorte mit erweiterter Authentifizierung, nicht standardmäßigen Ports oder Firewall-Zugriffsverhandlungen.

Wenn Sie häufig Fernzugriff durchführen (Teil Ihrer Hauptrolle), rechtfertigt diese Anwendung ihre Kosten im ersten Nutzungsmonat.

david6
quelle
Entschuldigung, ich verstehe nicht. können Sie erklären ?
Netmoon
1
für Sie umformuliert ..
David6
2
Seit der Veröffentlichung der obigen Antwort wurden mehrere Iterationen von SecureCRT durchgeführt, einschließlich der neuesten Version von VanDyke, die Anfang Dezember 2013 veröffentlicht wurde. Mit jeder Iteration wurde das Programm verbessert, wodurch es noch vielseitiger wurde. Es hat auch eine reichhaltige API, mit der das Programm mit Python / VB-Skripten gesteuert / verbunden werden kann. SecureCRT ist seit einem guten Jahrzehnt Teil meines Kern-Toolkits, und ich kann es nur empfehlen.
Ville
Einverstanden. Ich teste weiterhin jede neue Version im Beta-Modus und war maßgeblich an den frühen Tests für die Portierung auf Ubuntu beteiligt .
David6
2

Bei Beantwortung der von Ihnen gestellten Frage ist es nicht möglich, ein Standardkennwort in einer ssh-Konfigurationsdatei zu konfigurieren.

Aber wenn es tatsächlich so ist, wie Sie sagen, "weil ich manchmal vom PC wegstehe und wenn ich zurückgehe, ein Passwort eingebe und auf Enterdas Terminal drücke CONNECTION CLOSED" , warum dann nicht stattdessen verhindern, dass die Sitzung geschlossen wird? SSH kann Verbindungen für Sie am Leben erhalten.

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

Danke, Arek für die Inspiration ...

Anstatt einen anderen Shell-Prozess auszuführen, ist dies nur eine Funktion, die in der aktuellen Bash-Shell ausgeführt wird. Es führt einen einzelnen awkBefehl aus, um die Konfigurationsdatei zu analysieren und herauszufinden, ob das Kennwort aus einer Shell-Variablen oder aus dem im Klartext geschriebenen Kennwort in die ssh-Konfigurationsdatei übernommen werden soll (mit awkeiner evalanstelle von describeaufgrund von Problemen getroffenen Verwendung describe).

Ich habe so viele Möglichkeiten ausprobiert, ProxyCommand sshpassdirekt in einer sshKonfigurationsdatei zu verwenden, aber nichts schien wie erwartet zu funktionieren, außer wenn ich mich über RSA an einer Box anmelden konnte. Aber dann musste ich ein Passwort senden, um mein verschlüsseltes Verzeichnis zu öffnen. Die folgende Funktion scheint jedoch in allen Fällen für mich zu funktionieren, auch für 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)

Dann ~/.ssh/configsieht ein Abschnitt so aus:

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

Wenn #Passvar im Konfigurationsabschnitt ein vorhanden ist, wird das überschrieben #Password.
$MYPASS_ENVVARist die Umgebungsvariable, die Ihr Passwort enthält.

Genießen!

MerryDan
quelle
1

Die Antwort von @BrunoPereira auf diese Frage zeigt eine alternative Methode, um eine Verbindung herzustellen, ohne explizit ein Kennwort einzugeben und ohne ssh-Schlüssel.

Sie können ein Skript, einen Alias ​​oder eine Funktion in Ihrem erstellen, ~/.bashrcum diesen Befehl schnell auszuführen.

Offensichtlich gibt es Sicherheitsaspekte, die Sie bei diesem Ansatz berücksichtigen sollten.

Enzotib
quelle
Es ist großartig, dass Sie eine Verknüpfung zu einer Lösung herstellen. Es empfiehlt sich jedoch auch, die Lösung hier zu veröffentlichen. Auf diese Weise gibt es hier immer noch eine brauchbare Antwort, falls der Link jemals entfernt wird (wie dies gelegentlich beim Stapelaustausch der Fall ist).
Paul
0

Hier ist meine ausführliche Variation der Antwort von @ ArekBurdach. Es bietet folgende Erweiterungen:

  • Der Host kann sich an einer beliebigen Stelle in der sshBefehlszeile befinden. dh es unterstützt auch die ssh <args> <host> <commands>Syntax
  • Der Pfad zu wird nicht hartcodiert ssh
  • robusteres Parsen von ssh_config
  • Bonus: Wrapper scpauch dafür

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

Definieren Sie Aliase in Ihrem ~/.bashrc:

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

Aufbau

Beschwert sich mit der IgnoreUnknownDirektive sshnicht über eine neu eingeführte PasswordDirektive, so können wir (im Gegensatz zu @ ArekBurdachs Antwort) diese als "echte" Konfiguration erscheinen lassen. Wenn Ihnen das nicht gefällt, ist es trivial, das Skript wieder in das auskommentierte zu ändern.

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

Host foohost
    User baruser
    Password foobarpassword
Ingo Karkat
quelle
0

Wenn Sie keinen direkten Zugriff auf das Schlüsselpaar haben, können Sie das Kennwort auf Ihrem lokalen Computer verschlüsseln.

Die Möglichkeit besteht darin, Ihr Kennwort zusätzlich zu @Eric Woodruffs ProxyCommand mit einem Schlüssel zu verschlüsseln.

Eine Möglichkeit zum Kombinieren ist die Verwendung von Pipe:

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

wo

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

Es gibt eine kleine Variante eines im Blog beschriebenen Weges zur Verwendung, sshpass die hier zu finden ist . Vorausgesetzt, Sie haben ein gpg-verschlüsseltes Passwort (wie dies im Blog beschrieben wird), können Sie so etwas tun:

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

und speichern Sie diesen Befehl einfach als Alias ​​in Ihrem .bashrc.

Wenn Sie durch diese Verbindung tunneln möchten, können Sie so etwas tun

 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
quelle