はじめに
SFTPコマンドは、基本は対話形式ですが、batch modeやヒアドキュメントを使えば、非対話形式で実行することもできます。セキュリティの都合上、システム間のファイル連携を、SFTPサーバ経由でする、といったことは、今でもよくある話です。今回は、一番面倒な、パスフレーズ付きの秘密鍵を使った、公開鍵認証方式でいきます。
また、今更な話題ですが、opensshの開発チームが、scpは古くて使いづらく、sftpかrsyncを使うのを推奨するというのを、2019年4月に出しています。
The scp protocol is outdated, inflexible and not readily fixed. We
recommend the use of more modern protocols like sftp and rsync for
file transfer instead.
この流れは続いてるらしく、scpからsftpへの置き換えを検討しているようです。
A near-future release of OpenSSH will switch scp(1) from using the
legacy scp/rcp protocol to using SFTP by default.
サーバ間のファイルのやりとりは、sftpかrsyncのどちらかに今後はなっていくと思われます。
事前準備
パスフレーズつきの秘密鍵
いまどきは、ed25519で作成したいものです。
$ ssh-keygen -t ed25519
...
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
そうもいかない場合は、RSAの4096bitでいきましょう。
ssh-keygen -t rsa -b 4096
パスフレーズを標準出力するシェルスクリプト
下記のようなものを作成しておきます。
# !/usr/bin/env bash
echo "${鍵作成時に入力したパスフレーズ}"
もちろん、実行権限をつけます
chmod +x askpass.sh
ssh-agent + ssh-add + SSH_ASKPASS
- ssh-agentを起動
- ssh-addで、作成した秘密鍵を登録
- パスフレーズの入力は、SSH_ASKPASSに、パスフレーズを出力するスクリプトのパスを設定
- sftpコマンドが終わったら、ssh-agentを停止
$ eval `ssh-agent`
$ DISPLAY=":0.0" SSH_ASKPASS=askpass.sh setsid ssh-add id_ed25519 </dev/null
$ sftp ${sftp_user}@${sftp_server}
sftp>
...
sftp> quit
$ ssh-agent -k
これで、秘密鍵のパスフレーズ入力が、対話なしでできるようになりました。
あとは、sftpサーバ上で実行するコマンドの部分です。これはヒアドキュメントを使えばいいです。
sftpコマンドを使ったシェルスクリプトは、下記のようになります。
# !/usr/bin/env bash
set -euo pipfail
sftp_user=...
sftp_server=...
eval `ssh-agent`
DISPLAY=":0.0" SSH_ASKPASS=askpass.sh setsid ssh-add ~/.ssh/id_ed25519 </dev/null
sftp ${sftp_user}@${sftp_server} << EOF
put local_file /dst
put local_file2 /dst
get /from/remote_file
quit
EOF
参考