web-dev-qa-db-ja.com

.ssh / configでパスワードを設定して自動ログインを許可できますか?

私はubuntu 11.10を使用しています。毎日多くのサーバーに接続するためにsshを使用しているので、.ssh/configファイルにパラメーターを入れます。このような :

Host Home
User netmoon
Port 22
HostName test.com

接続ごとに、このファイルにパスワードを入れる方法はありますか?したがって、サーバーがパスワードを要求すると、端末はパスを入れてサーバーに送信します。

時々、PCから離れて、戻ってパスワードを入力し、Enterキーを押すと、端末は接続が閉じられたと言ったからです。

  • 公開鍵と秘密鍵のペアを使用したくありません。
90
Netmoon

セキュリティと利便性のトレードオフは決して終わりません...

ssh-copy-idパッケージのopenssh-clientを使用できますか?

man ssh-copy-idから:

ssh-copy-idは、sshを使用してリモートマシンにログインし、指定されたIDファイルをそのマシンの〜/ .ssh/authorized_keysファイルに追加するスクリプトです。

54
waltinator

本当に公開/秘密キーペアを使用したくない場合は、expectスクリプトを記述して、宛先アドレスに応じて自動的にパスワードを入力できます。

編集:私が意味するのは、一方ではexpectを使用してパスワードを入力し、他方では構成ファイルから特定のユーザーとホストのパスワードを読み取るスクリプトを作成できるということです。たとえば、次のpythonスクリプトは、晴れた日のシナリオで機能します。

#!/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 __== '__main__':
    parser = argparse.ArgumentParser(description='Run ssh through pexpect')
    parser.add_argument('url')
    args = parser.parse_args()
    main(args)

構成ファイルの形式は次のとおりです。

[user_1]
Host1 = passwd_1
Host2 = passwd_2

[user_2]
Host1 = passwd_1
Host2 = passwd_2

注:説明したように、pythonスクリプトは、sshからのすべての考えられるエラーと質問メッセージとすべての考えられるURLを処理するために、はるかに複雑である必要があります(例では、user@Host、ただしユーザー部分はほとんど使用されません)、しかし基本的な考え方は同じです。構成ファイルについては、別の構成ファイルを使用するか、.ssh/configを使用して独自のコードを記述し、そのファイルを解析して、特定のユーザーとホストのパスワードを取得できます。

25
jcollado

そのためのsshpassプログラムもあります。使用方法:sshpass -p MyPa55Word ssh [email protected]

18
igor

ProxyCommandはどうですか:

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

ncの代わりにssh -Wも使用できます。

ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p
18
Eric Woodruff

いいえ。これは不可能です。

唯一の本当の代替手段は秘密鍵を使用することですが、あなたはしたくないと言いました(なぜですか?)。

15
Caesium

/ usr/local/binに単純なsshスクリプト置換を作成できます。

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

そして、〜/ .ssh/configファイルで使用できます

Host foohost
    User baruser
    #Password foobarpassword
8
Arek Burdach

VanDyke SoftwareのSecureCRTというアプリケーションを使用しています。

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

無料ではありませんが、非常にリーズナブルな価格です。リモートアクセス、ターミナルエミュレーション、および(分散)ネットワーク管理のために、何年も(Windows上で実行するか、Wineを使用して)使用しました。彼らはついに2011年の初めにこれのネイティブLinuxバージョンをリリースしました。

複雑なログイン設定(またはスクリプト)、保存されたパスワード(または証明書)、タブ付きの複数セッションなどをサポートしています。

起動時に、保存されたリモート(またはローカル)マシンの構造化リスト(ツリービュー)からどのリモートターゲット(およびプロトコル)を選択するか、単に接続を作成します(その後保存されます)。

これは、高度な認証、非標準ポート、またはファイアウォールアクセスネゴシエーションを備えたリモートサイトに特に役立つことがわかりました。

リモートアクセスを頻繁に行う場合(メインロールの一部)、このアプリケーションは使用の最初の1か月で費用を正当化します。

4
david6

あなたが尋ねた質問に答えると、いいえ、ssh configファイルでデフォルトのパスワードを設定することはできません。

しかし、実際に「PCから離れて戻ってパスワードを入力し、Enterキーを押したときに、端末がCONNECTION CLOSED。」と言ったためです "代わりにセッション? SSHは接続を維持します。

Host Home
  User netmoon
  Port 22
  HostName test.com
  ServerAliveInterval 300
  ServerAliveCountMax 2

この質問 に対する@BrunoPereiraの答えは、パスワードを明示的に入力せずにsshキーを使用せずに接続する代替方法を示しています。

~/.bashrcにスクリプト、エイリアス、または関数を作成して、そのコマンドをすばやく実行できます。

明らかに、このアプローチでは考慮すべきセキュリティ上の考慮事項があります。

1
enzotib

インスピレーションをくれたArekに感謝...

別のシェルプロセスを実行するのではなく、これは現在のbashシェルで実行される単なる機能です。単一のawkを実行して構成ファイルを解析し、シェル変数からパスワードを取得するか、ssh構成ファイルにクリアテキストで書き込まれたパスワードを取得するかを判断します(describeを使用して問題が発生したため、devalの代わりにawkをevalに使用)。 ProxyCommandを使用してssh configファイルでsshpassを直接使用する方法を数多く試しましたが、rsaを介してボックスにログインできたが、暗号化されたディレクトリを開くためにパスワードを送信する必要があった場合を除いて、期待どおりに動作するようには見えませんでした。しかし、私の以下の機能は、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)

~/.ssh/configセクションは次のようになります。

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

#Passvarが構成セクションに存在する場合、これは#Passwordをオーバーライドします。
$MYPASS_ENVVARは、パスワードを保持する環境変数です。

楽しい!

1
MerryDan

キーペアに直接アクセスできない場合は、ローカルマシンでパスワードを暗号化できます。

その方法は、@ Eric WoodruffのProxyCommandに加えて キーを使用してパスワードを暗号化 です。

組み合わせる方法はパイプを使用することです:

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
0
Willian Z

ブログで説明されているsshpassの使用方法については、 here で見つけることができる若干の変形があります。 gpgで暗号化されたパスワード(これはブログで説明されています)ファイルがある場合、次のようなことができます。

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

そのコマンドをエイリアスとして.bashrcに保存するだけです。

その接続をトンネリングする場合は、次のようなことができます

 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
0
ricffb

これは、@ ArekBurdachの答えに関する私の手の込んだバリエーションです。以下の拡張機能を提供します。

  • Hostsshコマンドラインのどこでもかまいません。つまり、ssh <args> <Host> <commands>構文もサポートしています
  • sshへのパスをハードコードしません
  • ssh_configのより堅牢な解析
  • ボーナス:scpのラッパーも

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

~/.bashrcでエイリアスを定義します:

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

設定

IgnoreUnknownディレクティブを使用すると、sshは新しく導入されたPasswordディレクティブについて文句を言わないので、(@ ArekBurdachの答えとは対照的に)これを「実際の」構成として表示できます。これが気に入らない場合は、スクリプトをコメントアウトされたものに戻すのは簡単です。

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

Host foohost
    User baruser
    Password foobarpassword
0
Ingo Karkat