SSH のパスワード認証を自動化させてみた.
こんにちは.あらい大先生です.
SN実験3 の C プログラム脆弱性実習では,SSH を用いて実習環境の Linux マシンにログインします.
Windows PC でログインする場合,手順は色々とありますが,以下の理由で WSL を活用すると良いでしょう.
- SN コースのプログラミング演習1で WSL を利用するから.
- Linux 版の OpenSSH は不具合を起こしにくいから [1].
ただ,WSL の SSH を用いて実習環境へログインするためには,以下の作業が必要になります.
- WSL を起動する(コマンドプロンプトで wsl コマンドを実行する).
- ssh ユーザ名@ホスト名 を入力して実行する.
- パスワードを入力(コピペ)する.
これでは面倒なので,「ワンクリックで Python の仮想環境を有効にする.[2] のように,ワンクリックで実習環境へログインできないか?」と思いました.
そこで,「SSH 自動化」で調べてみると,expect コマンドを利用すると実現できるという記事 [3] が見つかったので,真似してみることにしました.
手順
必要に応じて,以下のコマンドを実行しましょう.
sudo apt update
sudo apt upgrade -y
sudo apt install expect
先ほど紹介した記事 [3] を参考にして,WSL 環境で以下のシェルスクリプトを作成して,適当なディレクトリに保存します.
Windows 環境で作成して WSL 環境へ移動させる方法でも良いですが,Windows と Linux とで改行文字が異なること [4] に注意しましょう.
#!/bin/bash
expect -c "
set timeout 5
spawn ssh ${USER_NAME}@${HOST_NAME}
expect \"password\"
send \"\n${PASSWORD}\"
expect \"${STRING}\"
interact
"
実習環境へログインしたいのであれば,${USER_NAME}
には RAINBOW ID,${HOST_NAME}
には実習環境のホスト名(manaba+R で確認できます),${PASSWORD}
にはメールに記載されたパスワードが入ります(認証情報をハードコーディングすべきではありませんが,ソースコードを外部に公開するわけではないので良しとしましょう).
また,${STRING}
には,ログインが成功したときにのみ出力される文字列を入れれば良いです.
次に,Windows で以下のバッチファイルを作成します.
wsl ~/ssh_login.sh
利用する WSL を指定したい場合,wsl の後ろに -d <Distro>
を追加します.<Distro>
にはディストリビューションが入ります.
ディストリビューションの一覧を確認したい場合,wsl -l
を実行しましょう.
このバッチファイルを Windows のタスクバーにピン留めしたい場合,ワンクリックで Python の仮想環境を有効にする.[2] を参考にしましょう.
動作確認
2022年10月15日現在,実習環境へログインすることはできないみたいなので,学内の Linux へログインすることにしました.
そのため,${HOST_NAME}
には 学内のリモートログインサーバ [5] のホスト名,${PASSWORD}
には RAINBOW へログインするためのパスワードを入れます.
次に,${STRING}
へ入れる文字列を決めるために,試しに学内の Linux へログインしています.
ログインしてみると,以下の文字列が出力されました.
Last login: Sat Oct 15 10:33:52 2022 from (略)
Last login:
の後ろは,前回にログインした時刻やログイン元のホスト名なので,常に同じ文字列が出力されるとは限りません.
一方,Last login:
という文字列は変わらなそうなので,login
という文字列を ${STRING}
へ入れることにしました.
それでは,バッチファイルを実行して動作確認をしてみましょう.
手動でログインしたときと同じような出力が得られれば成功です.
おわりに
SSH のパスワード認証を自動化してみました.
今回は学内 Linux への自動ログインで動作確認を行いましたが,SN実験3 の実習環境でも上手くいくと思います.
来年度に SN実験3 を行う学生さん,TA さんは是非とも検証してほしいです.
参考
- 上原哲太郎:sshの利用 Windowsの場合,プログラミング言語サポートページ,入手先〈https://scrapbox.io/Ritsumei-ISE-SN/ssh%E3%81%AE%E5%88%A9%E7%94%A8%E3%80%80Windows%E3%81%AE%E5%A0%B4%E5%90%88〉(参照 2022-10-15).
- 荒井康汰:ワンクリックで Python の仮想環境を有効にする.,立命館大学情報理工学部サイバーセキュリティ研究室,入手先〈https://cysec.ise.ritsumei.ac.jp/2022/09/12/%e3%83%af%e3%83%b3%e3%82%af%e3%83%aa%e3%83%83%e3%82%af%e3%81%a7-python-%e3%81%ae%e4%bb%ae%e6%83%b3%e7%92%b0%e5%a2%83%e3%82%92%e6%9c%89%e5%8a%b9%e3%81%ab%e3%81%99%e3%82%8b%ef%bc%8e/〉(参照 2022-10-05)
- ine1127:Linuxの対話がめんどくさい?そんな時こそ自動化だ!-expect編-,Qiita,入手先〈https://qiita.com/ine1127/items/cd6bc91174635016db9b〉(参照 2022-10-15).
- 上原哲太郎:改行文字の問題,プログラミング言語サポートページ,入手先〈https://scrapbox.io/Ritsumei-ISE-SN/%E6%94%B9%E8%A1%8C%E6%96%87%E5%AD%97%E3%81%AE%E5%95%8F%E9%A1%8C〉(参照 2022-10-15).
- 立命館大学:リモートログインサーバーを利用する,RITSUMEIKAN ITサポートサイト,入手先〈https://it.support.ritsumei.ac.jp/hc/ja/articles/900006923803〉(参照 2022-10-15).
手元で確認したところ、以下のところを変更したらうまくいきました。
パスワードを入れた後にエンター(\n)を送信するのが正しいのではないでしょうか?
send \"\n${PASSWORD}\"
-> send \"${PASSWORD}\n\"