web-dev-qa-db-ja.com

SSHはパスワードを1回要求し、タイムアウトが終了するまでパスワードを再利用します

この問題を解決するにはどうすればよいですか?私はbashスクリプト(Ubuntu Serverの下)を持っており、いくつかのSSH接続を行い、rsyncのようなリモート転送を複数回実行します。

私の問題は、パスワードを複数回入力することを避けたいということです。しかし、SSH公開鍵交換は使いたくありません。誰かが鍵を持っていれば、リモートコンピューターに接続できるからです。

以下をお願いします:

  • Bashスクリプトを開始すると、SSHはパスワードを要求するはずです
  • パスワードを再利用するため、タイムアウトするまでパスワードを要求しない
  • タイムアウトが終了したら、もう一度パスワードを尋ねます。

Sudoがsshでどのように機能しているか、似たようなもの。

これを解決する方法はありますか?

EDIT1:

ssh multiplexingという名前の新しいSSH機能を見つけました。たぶんこれを使用して、私が望む目標に到達することができます。

https://unix.stackexchange.com/questions/50508/reusing-ssh-session-for-repeated-rsync-commands

これはうまくいくでしょうか?

3
klor

私は自分のニーズに最適なソリューションを見つけたようです:

rsyncコマンドを繰り返し実行するためにsshセッションを再利用する

#!/bin/bash

# Create ssh-mux (SSH multiplex) dir only if not exists
[[ ! -d dir ]] || mkdir ~/.ssh/ssh-mux

Apache_site_path_source="/var/www/source_site"
Apache_site_path_target="/var/www/target_site"

# Solution: Start SSH multiplexing session (works fine)
# https://unix.stackexchange.com/questions/50508/reusing-ssh-session-for-repeated-rsync-commands
Sudo ssh -nNf -o ControlMaster=yes -o ControlPath="~/.ssh/ssh-mux/%L-%r@%h:%p" [email protected]

Sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${Apache_site_path_source}/. ${Apache_site_path_target}/;
printf "\n\n\n\n\n\n"
Sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${Apache_site_path_source}/. ${Apache_site_path_target}/;
printf "\n\n\n\n\n\n"
Sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${Apache_site_path_source}/. ${Apache_site_path_target}/;
printf "\n\n\n\n\n\n"

# Finish SSH multiplexing session
Sudo ssh -O exit -o ControlPath="~/.ssh/ssh-mux/%L-%r@%h:%p" [email protected]

このソリューションは、パスワードを1回だけ尋ね、次にパスワードを再度尋ねることなくrsyncを3回実行します。各rsyncはSSH多重化を使用してSSH接続を再利用します。

SSH構成を変更し、SSH多重化設定を保存することは可能ですが、このソリューションを使用すると、サーバー構成を変更する必要がなく、スクリプトはそのまま機能します。

0
klor

(私のコメントを klor からのリクエストごとの回答として再投稿します)。

聞きたいことではありませんが、これが鍵ベースの認証の目的です。秘密鍵にパスフレーズを付ける限り、パスワード認証と同じくらい安全です。

ssh-agentを使用すると、毎回パスフレーズを入力する必要がなくなります。-tssh-agentオプションを使用すると、タイムアウトの動作を確認できます。

# start a Shell under ssh-agent with a 5-minute timeout for keys loaded with ssh-add
ssh-agent -t 300 /bin/bash

# add your key(s) to the agent; ssh-add will Prompt for passphrase, if one is set
ssh-add

# do some stuff
ssh remote.server cat /some/file
rsync file1 file2 [email protected]:/some/directory

# after 300 seconds, timeout reached, run ssh-add again to re-add your keys
ssh-add

スクリプトには、タイムアウトが発生するタイミングを判断するためのロジックが必要です。 1つの方法は、sshrsync-o BatchMode=yesで実行することです。これにより、インタラクティブな認証方法が妨げられるため、キーが使用できなくなった場合、sshは終了しますパスワードを要求する代わりに。終了コードを使用して、ssh-addを再度実行する必要があるかどうかを判断できます。この場合、$?255に設定する必要があります。

パスフレーズをssh-addにフィードする方法は、プログラムで受け入れる方法が提供されていないため、引き続き解決する必要があります。スクリプトが手動で入力するように要求しない限り、おそらくその部分にexpectを使用する必要があります。これは、パスフレーズをどこかにハードコーディングすることを意味します。

3

James Sneeringer のコメントをプロファイルスクリプトとして実装。

# This script must be sourced to be useful. For example, if you name this script 
# ~/.bash_autossh, at the end of .bashrc, source $HOME/.bash_autossh
# Tested in bash & zsh
# MIT license, if you need a license.

# An absolute path to a private key:
AUTOLOADSSHID=$HOME/.ssh/id_ecdsa
# Timeout is in seconds, optional:
SSHID_TIMEOUT=60

auto_init_ssh_agent() {
  if [ "${SSH_AGENT_PID}x" = "x" ] || \
     [ "${SSH_AUTH_SOCK}x" = "x" ] || \
     ps -p "${SSH_AGENT_PID}" >& /dev/null || \
     [ ! -e "${SSH_AUTH_SOCK}" ]; then
    # There are problems with the agent, initialize a new agent.
    # Agents started this way should be manually stopped with ssh-agent -k
    source <(ssh-agent -s)
  fi
  if ! ssh-add -l | grep "${AUTOLOADSSHID}" >/dev/null; then
    # The autoload key is not present, try to load it.
    SSH_ADDTL_ARGS=()
    if [ "${SSHID_TIMEOUT}x" != "x" ]; then
      SSH_ADDTL_ARGS+=( -t "${SSHID_TIMEOUT}" )
    fi
    # This may ask for a password, as appropriate
    ssh-add "${SSH_ADDTL_ARGS[@]}" "${AUTOLOADSSHID}"
    unset SSH_ADDTL_ARGS
  fi
}

_autossh() {
  args=( "$@" )
  auto_init_ssh_agent
  ssh "${args[@]}"
}

alias autossh=_autossh

次に、コマンドautossh myserverそして、エージェントが利用できない場合、エージェントを自動初期化します。エイリアスは、スクリプトからインタラクティブ関数を誤って呼び出すのを防ぐためのものです。

問題として、WMセッションでエージェントを自動的に開始しないシステムでは、これによりssh-agentプロセスがマシンに散らばる可能性があり、ssh-agent -kで終了するか、killall ssh-agent。ログインセッション全体または複数のプロセスセッションで単一のssh-agentを共有する場合は、追加のスクリプトが必要になることがあります。

0
Andrew Domaszek