【30分で完了】SSH接続のパスフレーズを省略する方法
こんにちは。早速ですが、以下の文章を読んだうえで進むようにしてください。
今回、パスフレーズをテキストに記載して自身の端末に保存します。パスフレーズetcを平文でファイルに保存することはセキュリティの観点から推奨されません。そのリスクを十分に理解して可能な限り安全な環境下で使用してください。
今回の記事を執筆する理由は、私はいつも自分のPC端末→ConoHa VPS(Ubuntu)へSSH接続して遊んでいます。そんな中で、
毎回のSSH接続がめんどくさい。
と思うようになったわけです。公開鍵認証を採用にしているのでパスワード入力はないのですが、パスフレーズ入力があるんですよね、、
「Enter passphrase for key 〜」
↑これです。これがめんどくさい。「入力するだけで大した作業じゃないじゃん。」って言われそうですが、私は気になってしょうがない。
そこで今回の目標は
「ssh conoha」 と入力したら1発でSSH接続できる
ことを目標とします。
本ブログ内のSSHに関するまとめ記事を書いたので、こちらもご覧ください。
今回の前提を以下に書きます。
<接続先VPSサーバ情報>
サーバ:ConoHa VPS
OS:Ubuntu22.04
※公開鍵認証の設定が終わっていること
SSH関連のもろもろ設定手順については以下の記事で解説してますので、ご一読いただけると幸いです。
それでは始めていきましょう。
問題点の整理と改善方針
今回、問題点となっているのは以下のコマンドで公開鍵認証でSSH接続した際に、
ssh -i ~/.ssh/[秘密鍵ファイル] [ユーザ名]@[接続先IPアドレス] -p [接続先ポート番号]
以下の文言が出力され、パスフレーズを入力する必要があります。
Enter passphrase for key '/home/ユーザー名/.ssh/秘密鍵ファイル名':
色々と調べていると「ssh-agent」を使って秘密鍵を登録してパスフレーズを省略できることがわかりました。このコマンドはSSHキーの管理を行うプログラムで秘密鍵のロードや保持、そしてSSH認証リクエストに対する鍵を提供します。実際にこちらのコマンドを使って秘密鍵を登録する流れとしては以下となります。
① 「ssh-agent」コマンドを実行して、生成される環境変数情報を取得
② 環境変数情報をセット
③ 「ssh-add ~/.ssh/秘密鍵ファイル名」で秘密鍵を登録
④ パスコードを入力
⑤ 以降、パスフレーズを入力不要でSSH接続することが可能
ただし、こちらの流れで実施した場合は作業が終了してTerminal等のCLIを閉じると、もう一度①からやり直しになってしまいます。
それは嫌だ。
そこで、CLIを開いたと同時に①〜④のコマンドが実行できれば問題解決できると考えました。具体的には「.bash_profile」ファイルを活用します。このファイルはBashシェルのユーザー固有の設定ファイルです。このファイルはユーザーがログインする度に自動的に読み込まれて環境変数の設定やプログラムの起動、各種初期化コマンドを実行できます。
そのため、改善方針としては以下とします。
『「.bash_profile」ファイルから①〜④を実行するシェルを呼び出す』
改善方針の課題
しかし、④の秘密鍵のパスフレーズを入力するのが少し厄介で考える必要があります。
ログインしたタイミングで順次コマンドを実行していくのですが、③を登録した際にパスフレーズが質問され、この質問に対して答える必要があります。そこで「expect」を使用します。
「expect」は自動化スクリプト内で対話的コマンド(ユーザーの入力を必要とするコマンド)を扱うために設計されています。このツールは特定の文字列(”期待値”)をコマンド出力から検出して、それに応じた入力(キーボード入力やコマンド実行など)を自動的に行うことができます。
以下のコマンドでインストールできます。
sudo apt update
sudo apt install expect
それでは実装していきましょう。
スクリプトを作成する
まずは「~/.bash_profile」を編集します。やってることは「ssh-agent」の起動とスクリプトの呼び出しです。
# ssh-agentの起動及び環境変数を設定する
eval $(ssh-agent -s)
# ~/.ssh/init_ssh.bashの実行
if [ -x ~/.ssh/init_ssh.bash ]; then
~/.ssh/init_ssh.bash || {
echo "初期化スクリプトの実行に失敗しました。"
}
fi
次に呼び出すスクリプトの中身です。上記でいうと「init_ssh.bash」のことです。
#!/usr/bin/env bash
ssh-add-expect() {
# 最初の引数をfilename変数に、二番目の引数をpassword変数に格納します。
filename=$1
password=$2
# expectスクリプトの開始。ヒアドキュメントを使用しています。
expect <<EOEXP
# expectコマンドのタイムアウトを5秒に設定します。
set timeout 5
# ssh-addコマンドを実行し、指定されたファイル名でSSHキーを追加します。
spawn ssh-add \$HOME/.ssh/$filename
# "Enter passphrase for" プロンプトが表示されるのを待ちます。
expect "Enter passphrase for"
# パスフレーズを送信します。"\r" は改行(エンターキーの押下)を意味します。
send "$password\r"
# コマンドの実行終了(EOF)を待ちます。
expect eof
EOEXP
}
# ~/.ssh/secret-key.txt ファイルを読み込み、
# その中の各行に対してssh-add-expect関数を呼び出します。
# 各行はカンマで区切られており、ファイル名とパスフレーズに分割されます。
while IFS=, read -r filename password; do
ssh-add-expect "$filename" "$password"
done < ~/.ssh/secret-key.txt
秘密鍵ファイル名とパスワードを記載している「~/.ssh/secret-key.txt」は以下のように書きます。
id_rsa,password #[秘密鍵ファイル名],[パスフレーズ]を書く,(カンマ)で区切ってください。
最後に~/.bash_profileの読み込みをします。
source ~/.bash_profile
以上で実装完了です。以下のコマンドを打ってみてエラーが出なければ問題なしです。
これでSSH接続した際にパスフレーズを質問されることはありません。
/.ssh/configファイルを作成する
パスフレーズの省略は完了したので、最後に「ssh 〇〇」と打てばSSH接続できるように設定ファイルを作成します。以下の「config」ファイルを作ってください。
sudo vi /.ssh/config
内容は以下です。
Host conoha # この部分がssh ◯◯の部分
HostName 111.222.333.444 #接続先IPアドレス
port 10022 #SSHポート番号
User user #ユーザー名
IdentityFile ~/.ssh/[秘密鍵ファイル名] #秘密鍵ファイルパス
これで「ssh conoha」と打てば自動的にログインできます。
まとめ
今回はSSH接続する際のパスフレーズ入力を省略し、ログインプロセスを簡略化する方法について解説しました。頻繁に繰り返される作業に対して少しの工夫を施すことによって、大きな時間短縮効果を生みだすことができました!