SSHを介して、ネットワーク上の複数のコンピューター(静的イーサネット)間で通信したい。これを行うには、特定のマシンにログインするたびにssh-addを実行する必要があります。これを行うには、一度セットアップして、ログインまたは再起動するたびにパスフレーズを要求しないようにします。私のマシン?
bash_profile
ファイルにいくつかの行を追加する方法があることはわかっていますが、特定のマシンに再起動/ログインするたびにパスワードを入力する必要があります。
if [ -z "$SSH_AUTH_SOCK" ] ; then
eval `ssh-agent -s`
ssh-add
fi
これは、セキュリティと利便性のトレードオフの典型的な例です。幸いにもいくつかのオプションがあります。最も適切なソリューションは、使用シナリオと必要なセキュリティレベルによって異なります。
ssh-key with passphrase、nossh-agent
認証にキーが使用されるたびに、パスフレーズを入力する必要があります。これはセキュリティの観点からは最良のオプションですが、最悪のユーザビリティを提供します。これは、繰り返し入力する負担を軽減するために、弱いパスフレーズが順番に選択されることにもつながります。
ssh-key with passphrase、withssh-agent
以下を~/.bash_profile
に追加すると、自動的にssh-agent
が開始され、ログイン時にsshキーがロードされます。
if [ -z "$SSH_AUTH_SOCK" ] ; then
eval `ssh-agent -s`
ssh-add
fi
ログインするたびにパスフレーズを入力する必要があります。使いやすさの観点からは少し優れていますが、ログインセッション中にキーを使用するかどうかに関係なく、ssh-agent
がパスフレーズを要求するという欠点があります。新しいログインごとに個別のssh-agent
インスタンスも生成され、明示的に強制終了しない限り、ログアウト後もメモリに追加されたキーで実行され続けます。
ログアウト時にssh_agent
を強制終了するには、~/.bash_logout
に以下を追加します
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
または以下を~/.bash_profile
に
trap 'test -n "$SSH_AUTH_SOCK" && eval `/usr/bin/ssh-agent -k`' 0
Collin Andersonの回答 のように、ファイルシステム内の固定された場所にエージェントへの永続的な通信ソケットを作成することで、複数のssh-agent
インスタンスの作成を回避できます。これは、複数のエージェントインスタンスを生成する場合よりも改善されていますが、明示的に強制終了しない限り、ログアウト後も復号化されたキーがメモリに残ります。
デスクトップでは、デスクトップ環境に含まれる Gnome Keyring SSH Agent などのssh-agentを使用すると、通常、最初にssh-keyでパスフレーズの入力を要求できるため、より優れたアプローチになります。ログインセッション中に使用され、セッションが終了するまで、復号化された秘密鍵をメモリに保存します。
ssh-key with passphrase、withssh-ident
ssh-ident
は、ユーザーに代わってssh-agent
を管理し、必要に応じてIDをロードできるユーティリティです。 ssh-agent
へのアクセスを必要とする端末、ssh、またはログインセッションの数に関係なく、必要なときに一度だけキーを追加します。また、接続されているホスト、またはディレクトリsshの呼び出し元に応じて、異なるエージェントと異なるキーのセットを追加して使用することもできます。これにより、異なるホストでエージェント転送を使用するときにキーを分離できます。また、GitHubなどのサイトで複数のアカウントを使用することもできます。
ssh-ident
を有効にするには、それをインストールし、次のエイリアスを~/bash_profile
に追加します。
alias ssh='/path/to/ssh-ident'
ssh-key with passphrase、withkeychain
keychain
は、ユーザーに代わってssh-agent
を管理し、ログインセッションの終了時にssh-agent
を実行したままにすることができる小さなユーティリティです。以降のログインでは、keychain
は既存のssh-agent
インスタンスに接続します。実際には、これは、再起動後の最初のログイン時にのみパスフレーズを入力する必要があることを意味します。以降のログインでは、既存のssh-agent
インスタンスの暗号化されていないキーが使用されます。これは、パスワードなしのsshキーなしでcron
ジョブでパスワードなしのRSA/DSA認証を許可する場合にも役立ちます。
keychain
を有効にするには、それをインストールし、次のようなものを~/.bash_profile
に追加します。
eval `keychain --agents ssh --eval id_rsa`
セキュリティの観点からは、ssh-ident
およびkeychain
は、特定のセッションの存続期間に制限されているssh-agent
インスタンスよりも劣りますが、高度な利便性を提供します。 keychain
のセキュリティを向上させるために、--clear
キーチェーンの呼び出しに~/.bash_profile
オプションを追加する人もいます。このようにすることで、上記のようにログイン時にパスフレーズを再入力する必要がありますが、cron
ジョブは、ユーザーがログアウトした後も暗号化されていないキーにアクセスできます。 keychain
wiki page には、より多くの情報と例があります。
ssh-key with passphrase
セキュリティの観点からは、秘密鍵が公開された場合に備えて完全に保護されていないため、これは最悪のオプションです。ただし、これは再起動後にパスフレーズを再入力する必要がないことを確認する唯一の方法です。
ssh-key with passphrase、withssh-agent
、passphrase tossh-add
スクリプトから
スクリプトからパスフレーズをssh-add
に渡すことは簡単なように思えるかもしれませんが、 echo "passphrase\n" | ssh-add
、これはssh-add
のように単純ではありません stdin
からパスフレーズを読み取りませんが、/dev/tty
を直接開いて読み取ります 。
これは、インタラクティブアプリケーションを自動化するためのツールである expect
を使用して 回避策 にすることができます。以下は、スクリプトに保存されているパスフレーズを使用してsshキーを追加するスクリプトの例です。
#!/usr/bin/expect -f
spawn ssh-add /home/user/.ssh/id_rsa
expect "Enter passphrase for /home/user/.ssh/id_rsa:"
send "passphrase\n";
expect "Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)"
interact
パスフレーズはスクリプトでプレーンテキストで保存されるため、セキュリティの観点から、これはパスワードなしのsshキーを使用するよりもはるかに優れていることに注意してください。このアプローチを使用する場合は、パスフレーズを含むexpect
スクリプトに適切な権限を設定し、鍵の所有者のみが読み取り、書き込み、実行できるようにすることが重要です。
これを~/.bashrc
に追加し、ログアウトして再度ログインすると、有効になります。
if [ ! -S ~/.ssh/ssh_auth_sock ]; then
eval `ssh-agent`
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l > /dev/null || ssh-add
これにより、再起動するたびに初めてログインするときにのみパスワードの入力を求められます。実行中であれば、同じssh-agent
を再利用し続けます。
OPの質問とはあまり関係ありませんが、他の人には役立つかもしれません。7.2.0以降、ssh(1)には、最初の認証時にssh-agentにキーを追加できるオプションがあります。オプションはAddKeysToAgent
で、yes
、no
、ask
、またはconfirm
に設定でき、システム全体または個人用.ssh/config
ファイル。
ssh-agent
は、ロック解除されたさまざまなsshキーをキャッシュするため、sshキーをパスワードで保護できますが、毎回入力する必要はありません。
ロック解除されたキーをキャッシュするには、それらのキーのロックを解除する必要があります。パスフレーズでロックされている鍵のロックを解除するには、これらのパスフレーズを知っている必要があります。
人間からの承認を必要としない方法(「パスワードの入力」など)は、システムを安全な状態にするだけではありません。また、ssh-agentの目的全体が無意味になります。
これをすべて言っても、パスワードで保護されていないsshキーを使用するだけで済みます(ヒット Enter キー生成中にパスワードを要求された場合)。パスワードがないため、ssh-agent
キャッシュする(しない)ために要求する必要はありません。
SSHパスフレーズを自動化するための回避策を次に示します。
パスフレーズを標準出力に出力する1行のスクリプトを作成します。例:
echo 'echo MY_SSH_PASSWORD' > ~/.print_ssh_password && chmod 700 ~/.print_ssh_password
重要:必ず先頭のスペースを にコピーして、パスワードを履歴に保存しないようにしてください 。
以下のいずれかの方法を使用します。
標準入力アプローチを使用する:
cat ~/.ssh/id_rsa | SSH_ASKPASS=~/.print_ssh_password ssh-add -
または 名前付きパイプ アプローチ:
名前付きパイプを作成する ( プロセス置換 を試すこともできます):
mkfifo --mode 0600 ~/.ssh_fifo
認証に使用するプログラムを指定して、ssh-add
を実行します。
cat ~/.ssh/id_rsa >~/.ssh_fifo | SSH_ASKPASS=~/.print_ssh_password ssh-add ~/.ssh_fifo
man ssh-add
の詳細については、 SSH_ASKPASS
を参照してください。
ログイン時にssh-add(ssh-agentを開く必要がある)はお勧めしません。これは、ssh-agentセクションがいつ終了するかを制御できず、1つのログインセクションでキーファイルを使用する必要がない場合にセキュリティリスクを引き起こす可能性があるためです。
むしろ、すべてのキーファイルが自動的に追加されたssh-agentのセクションサブシェルを開き、sshを使用する必要があるときに呼び出されるスクリプトを書くことをお勧めします。採用できるのであれば、読み続けてください。
次の2つの選択肢があります。
キーファイルが盗まれた場合、弱いセキュリティが設定されているキーのすべてのパスフレーズを削除します。 (したがって非推奨)
鍵には同じパスフレーズを使用してください。その後、ssh-add keyfile1 keyfile2 ...
、セクションごとに1回だけパスフレーズを入力する必要があります。
どちらの場合も、次のようなスクリプトファイル "ssh_keys_section.sh"を記述できます。
#!/bin/bash
# This script run a ssh-agent on a sub-Shell and automatically ssh-add all keyfiles at once.
# This agent ends when you type `exit` to close the sub-Shell.
exec ssh-agent bash -c "ssh-add /path/to/keyfile1 /path/to/keyfile2 ...; exec bash"
備考:
ssh-keygen -p -f keyfile
/path/to/yourterminal &
(OSに依存)以前はSteampoweredによって言及されたスクリプトを使用していましたが、ファイルを横に置いたままにしないため、以下のスクリプトを作成しました。
zsh
シェルのみで作業します。
#!/bin/sh
AGENT_BIN=`which ssh-agent`
AGENT_ADD_BIN=`which ssh-add`
AGENT_PID=`ps -fe | grep ${AGENT_BIN} | awk -vuser=$USER -vcmd="$AGENT_BIN" '$1==user && $8==cmd{print $2;exit;}'`
if [ -z "$AGENT_BIN" ]; then
echo "no ssh agent found!";
return
fi
if [ "" -eq "$AGENT_PID" ]; then
if read -sq "YN?Do you want to unlock your ssh keys?"; then
echo ""
output=`$AGENT_BIN | sed 's/echo/#echo/g'`
eval $output
$AGENT_ADD_BIN
fi
else
for f in "/proc/"*
do
cmdline=`cat "$f/cmdline"`
if [ "${AGENT_BIN}" -ef "${cmdline}" ]; then
export SSH_AUTH_SOCK=`cat $f/net/unix | grep --binary-file=text -oP '((/[^/]*?)+/ssh-[^/]+/agent\.\d+$)'`
export SSH_AGENT_PID=${f##*/}
break;
fi
done
fi
if [ ! -S ${HOME}/.ssh/ssh_auth_sock ]; then
eval $(ssh-agent)
ln -sf "${SSH_AUTH_SOCK}" ${HOME}/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=${HOME}/.ssh/ssh_auth_sock
ssh_keys=$(find -E ~/.ssh -type f -regex '.*(rsa$|pem)')
ssh_agent_keys=$(ssh-add -l | awk '{key=NF-1; print $key}')
for k in "${ssh_keys}"; do
for l in "${ssh_agent_keys}"; do
if [[ ! "${k}" = "${l}" ]]; then
ssh-add "${k}" > /dev/null 2>&1
fi
done
done
SSHのシングルサインオンソリューションは pam_ssh
。
この記事 によると、コンセプトは次のとおりです。
Sshを介して複数の* nixベースのマシンで作業している場合、別のボックスにアクセスするたびにパスワードを入力しなければならないことにうんざりしているでしょう。 sshでアクセスできるすべてのマシンに、別のパスワード(最初にサインオンしたもの以外)を入力せずにアクセスできる安全な方法があります。
これは実際には非常に簡単です。基本的には、公開鍵と秘密鍵のペアを作成して他のマシンに対して自分自身を認証し、PAMにログオン後にキーをロードするエージェントを生成させ、すべてのリモートにアクセスするためのシングルサインオンソリューションを提供しますマシン。このガイドでは、この設定について説明します。
これが実際に機能するかどうかは確認していません。
SSH_ENV="$HOME/.ssh/environment"
function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}
# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
#ps ${SSH_AGENT_PID} doesn't work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
ここでクレジットを付与: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html
このソリューションもここで承認されています: http://mah.everybody.org/docs/ssh
これを~/.bashrc
ファイルに追加します。
ssh-add -L|grep identities > /dev/null && ssh-add /path/to/ssh/private/key
これが決定的なスクリプトです。
$ PASSWを更新してから、ターミナルにコピーして貼り付けます
# <sshpass> via typinator
# Updated: 2017-01-18_21h36
#
# apt-get update -y; apt-get install expect -qy
# Pass this value to ssh-add
PASSW="myfancypass123"
# Define a name for this script
THIS_SCRIPT="$(date +%Y-%m-%d_%H-%M-%S-%N)".sh
# Create a fresh directory to work from / Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
# Output our bash script file - BEGIN
cat <<< '
#!/bin/bash
set -u # Stop if an unbound variable is referenced
set -e # Stop on first error
export HISTIGNORE="expect*";
# Normal CMDs
echo && echo "The process should take about 10 seconds:" && echo
eval "$(ssh-agent -s)"; sleep 0.5;
# Define VAR passed when this bash-script was launched
password="$@"
# Launch the expect magic
expect -c "
spawn ssh-add /root/.ssh/id_rsa
expect "?assword:"
send \"$password\r\"
expect "?password:"
send \"$password\r\"
expect eof"
export HISTIGNORE="";
export password="";
' > $THIS_SCRIPT
# Output our bash script file - END
# Ensure we are in the right path
cd ~/temp; ls -la; sleep 1;
# Run the bash script
chmod +x ./$THIS_SCRIPT; ./$THIS_SCRIPT "$PASSW"; unset password;
# Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
(おそらくパスワードなしの)キーを追加し、ssh-add
[〜#〜] x [〜#〜] :
DISPLAY= ssh-add -k /path/to/key </dev/null &>/dev/null
終了ステータスは、成功または失敗を示します。
私が認識している最良の方法は、この質問で満足のいく答えを見つけることができなかったため、前の作業から変更したPAMログインスクリプトを使用することです。
パスフレーズは、システムパスワードと強力な派生関数で暗号化されて保存されます。ログイン時に、システムパスワードを使用してパスフレーズを復号化し、エージェントに追加します。
https://github.com/capocasa/systemd-user-pam-ssh
提示されている他のすべてのソリューションに対する利点は、ブート時に手動でssh-addを実行するのと同等のセキュリティをゼロの労力で組み合わせていることです。追加のツールを必要とせず、ほとんどのシステム(OpenSSL)にデフォルトですでにインストールされている追加の依存関係があります。
パスワードマネージャーとしてタツノオトシゴを実行している場合 ...これはおそらく; D
あなたが探している目標を達成する別のソリューションは、ログイン時に自動ロック解除のためにタツノオトシゴにsshキーを単に追加することです。これの主な利点は、gdmを介してログインした後、またはキーにパスワードが設定されていても、ログインに使用した後は、キーのパスワードを入力する必要がないことです。これには、秘密鍵と公開鍵の両方が必要です。また、タツノオトシゴの命名規則に従う必要があります。デフォルトは受け入れ可能です(秘密鍵のid_rsaおよび公開鍵のid_rsa.pub ...privatekeynameおよびprivatekeyname.pub)
ログイン時に自動ロック解除するタツノオトシゴにsshキーを追加するには、 (Fedora25では、パスが他のディストリビューションのどこにあるかはわかりませんが、非常によく似ています)
/lib64/seahorse/seahorse-ssh-askpass /path/to/keys/here
私にとっては
/lib64/seahorse/seahorse-ssh-askpass ~/.ssh/id_rsa
(タツノオトシゴは、私の場合の公開鍵がid_rsa.pubであると自動的に想定します)
コマンドを実行した後、seahorseはかわいい小さなgtkパスワードフィールドをポップオープンして、秘密鍵のパスワードを入力します。または、パスワードなしでキーを生成した場合は、空白のままにします。
すべてがうまくいった場合、タツノオトシゴはプロンプトを出しません。ターゲットマシンにSSHで接続する必要があります。その後、タツノオトシゴはパスワードでグラフィカルにキーのロックを解除するように促します(これは1回のみ発生します)が、今回は少し違って見えるはずです; P(これはタツノオトシゴがタツノオトシゴをssh-addするためにいくつかの魔法をかける部分でもあると思います) )、および[〜#〜]オプション[〜#〜]を提供して、ログイン時にキーのロックを解除します。このオプションをチェックして、目標を達成します。
すべての回答を読んだわけではないので、この回答を試す前に、ssh-addを使って誰もがあなたに言ったことを元に戻すことをお勧めします。そうしないと、キーに問題が発生する可能性があります、idk。
MacOSでの私のセットアップは次のとおりです(.zshrc
、またはbashの場合は.bash_profile
で)。
# Kill then Load the ssh-agent and set the necessary env variables it outputs
sshRestart() {
# if all else fails
# pkill -u $(whoami) ssh-agent;
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
eval `ssh-agent -s`
ssh-add ~/.ssh/YOUR_KEY_FILE
echo "Restarted SSH agent"
}
if [ -z "$SSH_AUTH_SOCK" ] || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]] ; then
eval `ssh-agent -s` > /dev/null 2>&1
ssh-add ~/.ssh/YOUR_KEY_FILE > /dev/null 2>&1
fi
デフォルト値は|| [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]]
であるため、macOSでは/private/tmp/com.Apple.launchd.SOMETHINGHERE/Listeners
部分が必要です。そうでない場合、$SSH_AUTH_SOCK
は常に何かに設定されているため、@ Thomas Nymanの包括的な回答は失敗します。
次に.zlogout
(bashの場合は.bash_logout
)で:
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
MacOS Mojave 10.14.5でテスト済み